feature related cleanups
Subsystems (6)
Michael S. Tsirkin
maintainercover feature related cleanups
A minor cleanup around handling of feature bits: this fixes up terminology and adds build checks.
Lightly tested.
Michael S. Tsirkin (3):
virtio: dwords->qwords
virtio: words->dwords
vhost: use checked versions of VIRTIO_BIT
drivers/vhost/net.c | 14 +++++------ drivers/virtio/virtio.c | 8 +++---- drivers/virtio/virtio_debug.c | 2 +- drivers/virtio/virtio_pci_modern_dev.c | 6 ++--- include/linux/virtio.h | 2 +- include/linux/virtio_features.h | 33 ++++++++++++++++---------- include/linux/virtio_pci_modern.h | 8 +++---- scripts/lib/kdoc/kdoc_parser.py | 2 +- 8 files changed, 42 insertions(+), 33 deletions(-)
Signature · 1 line
MST
Michael S. Tsirkin
maintainerPATCH 1/3 virtio: dwords->qwords
A "word" is 16 bit. 64 bit integers like virtio uses are not dwords, they are actually qwords. Fix up macro names accordingly.
--- drivers/vhost/net.c | 10 +++++----- drivers/virtio/virtio.c | 8 ++++---- drivers/virtio/virtio_debug.c | 2 +- include/linux/virtio.h | 2 +- include/linux/virtio_features.h | 24 ++++++++++++------------ include/linux/virtio_pci_modern.h | 8 ++++---- scripts/lib/kdoc/kdoc_parser.py | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-)
drivers/vhost/net.c +5 -5
@@ -69,7 +69,7 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;"#define VHOST_DMA_IS_DONE (len) ((__force u32)(len) >= (__force u32)VHOST_DMA_DONE_LEN) -static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS ] = {VHOST_FEATURES | (1ULL <<VHOST_NET_F_VIRTIO_NET_HDR ) | (1ULL << VIRTIO_NET_F_MRG_RXBUF) |
@@ -1720,7 +1720,7 @@ static long vhost_net_set_owner(struct vhost_net *n)static long vhost_net_ioctl (struct file *f,unsigned int ioctl,unsigned long arg) { -u64 all_features[VIRTIO_FEATURES_DWORDS ]; +u64 all_features[VIRTIO_FEATURES_QWORDS ];struct vhost_net *n = f->private_data;void __user *argp = (void __user *)arg;u64 __user *featurep = argp;
@@ -1752,7 +1752,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,/* Copy the net features, up to the user-provided buffer size */ argp +=sizeof (u64); - copied =min (count,VIRTIO_FEATURES_DWORDS ); + copied =min (count,VIRTIO_FEATURES_QWORDS );if (copy_to_user (argp, vhost_net_features, copied *sizeof (u64)))return -EFAULT ;
@@ -1767,7 +1767,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,virtio_features_zero (all_features); argp +=sizeof (u64); - copied =min (count,VIRTIO_FEATURES_DWORDS ); + copied =min (count,VIRTIO_FEATURES_QWORDS );if (copy_from_user (all_features, argp, copied *sizeof (u64)))return -EFAULT ;
@@ -1783,7 +1783,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,return -EOPNOTSUPP ; } -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) +for (i =0 ; i <VIRTIO_FEATURES_QWORDS ; i++)if (all_features[i] & ~vhost_net_features[i])return -EOPNOTSUPP ;
drivers/virtio/virtio.c +4 -4
@@ -272,8 +272,8 @@ static int virtio_dev_probe(struct device *_d)int err, i;struct virtio_device *dev =dev_to_virtio (_d);struct virtio_driver *drv =drv_to_virtio (dev->dev.driver); -u64 device_features[VIRTIO_FEATURES_DWORDS ]; -u64 driver_features[VIRTIO_FEATURES_DWORDS ]; +u64 device_features[VIRTIO_FEATURES_QWORDS ]; +u64 driver_features[VIRTIO_FEATURES_QWORDS ];u64 driver_features_legacy;/* We have a driver! */
@@ -303,7 +303,7 @@ static int virtio_dev_probe(struct device *_d) }if (virtio_features_test_bit (device_features,VIRTIO_F_VERSION_1 )) { -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =0 ; i <VIRTIO_FEATURES_QWORDS ; ++i) dev->features_array[i] = driver_features[i] & device_features[i]; }else {
@@ -325,7 +325,7 @@ static int virtio_dev_probe(struct device *_d) goto err;if (drv->validate) { -u64 features[VIRTIO_FEATURES_DWORDS ]; +u64 features[VIRTIO_FEATURES_QWORDS ];virtio_features_copy (features, dev->features_array); err = drv->validate (dev);
drivers/virtio/virtio_debug.c +1 -1
@@ -8,7 +8,7 @@ static struct dentry *virtio_debugfs_dir;static int virtio_debug_device_features_show (struct seq_file *s,void *data) { -u64 device_features[VIRTIO_FEATURES_DWORDS ]; +u64 device_features[VIRTIO_FEATURES_QWORDS ];struct virtio_device *dev = s->private;unsigned int i;
include/linux/virtio.h +1 -1
@@ -177,7 +177,7 @@ struct virtio_device {union virtio_map vmap;#ifdef CONFIG_VIRTIO_DEBUG struct dentry *debugfs_dir; -u64 debugfs_filter_features[VIRTIO_FEATURES_DWORDS ]; +u64 debugfs_filter_features[VIRTIO_FEATURES_QWORDS ];#endif };
include/linux/virtio_features.h +12 -12
@@ -4,15 +4,15 @@#include <linux/bits.h> -#define VIRTIO_FEATURES_DWORDS 2 -#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_DWORDS * 64) -#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_DWORDS * 2) +#define VIRTIO_FEATURES_QWORDS 2 +#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_QWORDS * 64) +#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_QWORDS * 2)#define VIRTIO_BIT (b) BIT_ULL((b) & 0x3f) -#define VIRTIO_DWORD (b) ((b) >> 6) +#define VIRTIO_QWORD (b) ((b) >> 6)#define VIRTIO_DECLARE_FEATURES (name) \ union { \ u64 name; \ - u64 name##_array[VIRTIO_FEATURES_DWORDS];\ + u64 name##_array[VIRTIO_FEATURES_QWORDS];\ }static inline bool virtio_features_chk_bit (unsigned int bit)
@@ -34,26 +34,26 @@ static inline bool virtio_features_test_bit(const u64 *features, unsigned int bit) {return virtio_features_chk_bit (bit) && - !!(features[VIRTIO_DWORD (bit)] &VIRTIO_BIT (bit)); + !!(features[VIRTIO_QWORD (bit)] &VIRTIO_BIT (bit)); }static inline void virtio_features_set_bit (u64 *features,unsigned int bit) {if (virtio_features_chk_bit (bit)) - features[VIRTIO_DWORD (bit)] |=VIRTIO_BIT (bit); + features[VIRTIO_QWORD (bit)] |=VIRTIO_BIT (bit); }static inline void virtio_features_clear_bit (u64 *features,unsigned int bit) {if (virtio_features_chk_bit (bit)) - features[VIRTIO_DWORD (bit)] &= ~VIRTIO_BIT (bit); + features[VIRTIO_QWORD (bit)] &= ~VIRTIO_BIT (bit); }static inline void virtio_features_zero (u64 *features) { -memset (features,0 ,sizeof (features[0 ]) *VIRTIO_FEATURES_DWORDS ); +memset (features,0 ,sizeof (features[0 ]) *VIRTIO_FEATURES_QWORDS ); }static inline void virtio_features_from_u64 (u64 *features,u64 from)
@@ -66,7 +66,7 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) {int i; -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =0 ; i <VIRTIO_FEATURES_QWORDS ; ++i)if (f1[i] != f2[i])return false;return true;
@@ -74,14 +74,14 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2)static inline void virtio_features_copy (u64 *to,const u64 *from) { -memcpy (to, from,sizeof (to[0 ]) *VIRTIO_FEATURES_DWORDS ); +memcpy (to, from,sizeof (to[0 ]) *VIRTIO_FEATURES_QWORDS ); }static inline void virtio_features_andnot (u64 *to,const u64 *f1,const u64 *f2) {int i; -for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) +for (i =0 ; i <VIRTIO_FEATURES_QWORDS ; i++) to[i] = f1[i] & ~f2[i]; }
include/linux/virtio_pci_modern.h +4 -4
@@ -107,7 +107,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev,static inline u64 vp_modern_get_features (struct virtio_pci_modern_device *mdev) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_QWORDS ];vp_modern_get_extended_features (mdev, features_array);return features_array[0 ];
@@ -116,11 +116,11 @@ vp_modern_get_features(struct virtio_pci_modern_device *mdev)static inline u64 vp_modern_get_driver_features (struct virtio_pci_modern_device *mdev) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_QWORDS ];int i;vp_modern_get_driver_extended_features (mdev, features_array); -for (i =1 ; i <VIRTIO_FEATURES_DWORDS ; ++i) +for (i =1 ; i <VIRTIO_FEATURES_QWORDS ; ++i)WARN_ON_ONCE (features_array[i]);return features_array[0 ]; }
@@ -128,7 +128,7 @@ vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev)static inline void vp_modern_set_features (struct virtio_pci_modern_device *mdev,u64 features) { -u64 features_array[VIRTIO_FEATURES_DWORDS ]; +u64 features_array[VIRTIO_FEATURES_QWORDS ];virtio_features_from_u64 (features_array, features);vp_modern_set_extended_features (mdev, features_array);
scripts/lib/kdoc/kdoc_parser.py +1 -1
@@ -638,7 +638,7 @@ class KernelDoc: (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\1 \2[]'), (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + args_pattern + r'\)', re.S), r'dma_addr_t \1'), (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + args_pattern + r'\)', re.S), r'__u32 \1'), - (KernRe(r'VIRTIO_DECLARE_FEATURES\s*\(' + args_pattern + r'\)', re.S), r'u64 \1; u64 \1_array[VIRTIO_FEATURES_DWORDS]'), + (KernRe(r'VIRTIO_DECLARE_FEATURES\s*\(' + args_pattern + r'\)', re.S), r'u64 \1; u64 \1_array[VIRTIO_FEATURES_QWORDS]'), ] # Regexes here are guaranteed to have the end limiter matching
Signature · 1 line
MST
Re: [PATCH 1/3] virtio: dwords->qwords
Quoted 2 lines · Michael S. Tsirkin
A "word" is 16 bit. 64 bit integers like virtio uses are not dwords, they are actually qwords.
I'm having trouble with this....
This bit makes sense. 4x 16bits = 64 bits.
drivers/vhost/net.c MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" · line 72
Quoted 2 lines
drivers/vhost/net.c +1
-1-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS ] = {
If this was u16, and VIRTIO_FEATURES_QWORDS was 4, which the Q would imply, than i would agree with what you are saying. But this is a u64 type. It is already a QWORD, and this is an array of two of them.
I think the real issue here is not D vs Q, but WORD. We have a default meaning of a u16 for a word, especially in C. But that is not the actual definition of a word a computer scientist would use. Wikipedia has:
In computing, a word is any processor design's natural unit of data. A word is a fixed-sized datum handled as a unit by the instruction set or the hardware of the processor.
A word can be any size. In this context, virtio is not referring to the instruction set, but a protocol. Are all fields in this protocol u64? Hence word is u64? And this is an array of two words? That would make DWORD correct, it is two words.
If you want to change anything here, i would actually change WORD to something else, maybe FIELD?
And i could be wrong here, i've not looked at the actual protocol, so i've no idea if all fields in the protocol are u64. There are protocols like this, IPv6 uses u32, not octets, and the length field in the headers refer to the number of u32s in the header.
Andrew
Michael S. Tsirkin
maintainerRe: [PATCH 1/3] virtio: dwords->qwords
Quoted 6 lines · Andrew Lunn
Quoted 2 lines · Michael S. Tsirkin
A "word" is 16 bit. 64 bit integers like virtio uses are not dwords, they are actually qwords.
I'm having trouble with this....
Quoted 8 lines
This bit makes sense. 4x 16bits = 64 bits.
drivers/vhost/net.c MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" · line 72
Quoted 2 lines
drivers/vhost/net.c +1
-1-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS ] = {If this was u16, and
VIRTIO_FEATURES_QWORDSwas 4, which the Q would imply, than i would agree with what you are saying. But this is a u64 type. It is already a QWORD, and this is an array of two of them.
I don't get what you are saying here.
It's an array of qwords and VIRTIO_FEATURES_QWORDS tells you how many QWORDS are needed to fit all of them.
This is how C arrays are declared.
Quoted 17 lines
I think the real issue here is not D vs Q, but WORD. We have a default meaning of a u16 for a word, especially in C. But that is not the actual definition of a word a computer scientist would use. Wikipedia has:
In computing, a word is any processor design's natural unit of data. A word is a fixed-sized datum handled as a unit by the instruction set or the hardware of the processor.
A word can be any size. In this context, virtio is not referring to the instruction set, but a protocol. Are all fields in this protocol u64? Hence word is u64? And this is an array of two words? That would make DWORD correct, it is two words.
If you want to change anything here, i would actually change WORD to something else, maybe FIELD?
Quoted 6 lines
And i could be wrong here, i've not looked at the actual protocol, so i've no idea if all fields in the protocol are u64. There are protocols like this, IPv6 uses u32, not octets, and the length field in the headers refer to the number of u32s in the header.
Andrew
Virtio uses "dword" to mean "32 bits" in several places:
device-types/i2c/description.tex:The \field{padding} is used to pad to full dword.
pads to 32 bit
transport-pci.tex: u8 padding[2]; /* Pad to full dword. */
same
Under pci, the meaning is also generally as I use it here. E.g.:
Documentation/PCI/pci.rst:You can use pci_(read|write)_config_(byte|word|dword) to access the config
Signature · 1 line
MST
Re: [PATCH 1/3] virtio: dwords->qwords
Quoted 45 lines · Michael S. Tsirkin
Quoted 6 lines · Andrew Lunn
Quoted 2 lines · Michael S. Tsirkin
A "word" is 16 bit. 64 bit integers like virtio uses are not dwords, they are actually qwords.
I'm having trouble with this....
Quoted 8 lines
This bit makes sense. 4x 16bits = 64 bits.
drivers/vhost/net.c MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" · line 72
Quoted 2 lines
drivers/vhost/net.c +1
-1-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS ] = {If this was u16, and
VIRTIO_FEATURES_QWORDSwas 4, which the Q would imply, than i would agree with what you are saying. But this is a u64 type. It is already a QWORD, and this is an array of two of them.I don't get what you are saying here.
It's an array of qwords andVIRTIO_FEATURES_QWORDStells you how many QWORDS are needed to fit all of them.This is how C arrays are declared.
Quoted 22 lines
I think the real issue here is not D vs Q, but WORD. We have a default meaning of a u16 for a word, especially in C. But that is not the actual definition of a word a computer scientist would use. Wikipedia has:
In computing, a word is any processor design's natural unit of data. A word is a fixed-sized datum handled as a unit by the instruction set or the hardware of the processor.
A word can be any size. In this context, virtio is not referring to the instruction set, but a protocol. Are all fields in this protocol u64? Hence word is u64? And this is an array of two words? That would make DWORD correct, it is two words.
If you want to change anything here, i would actually change WORD to something else, maybe FIELD?
And i could be wrong here, i've not looked at the actual protocol, so i've no idea if all fields in the protocol are u64. There are protocols like this, IPv6 uses u32, not octets, and the length field in the headers refer to the number of u32s in the header.
Quoted 4 lines
Quoted 1 line
Andrew
Virtio uses "dword" to mean "32 bits" in several places:
It also uses WORD to represent 32 bits:
void
vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev,
u64 *features)
{
struct virtio_pci_common_cfg __iomem *cfg = mdev->common;
int i;
virtio_features_zero(features);
for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) {
u64 cur;
vp_iowrite32(i, &cfg->guest_feature_select);
cur = vp_ioread32(&cfg->guest_feature);
features[i >> 1] |= cur << (32 * (i & 1));
}
}And this is a function dealing features. So this seems to suggest a WORD is a u32, when dealing with features. A DWORD would thus be a u64, making the current code correct.
As i said, the problem here is WORD. It means different things to different people. And it even has different means to different parts of the virtio code, as you pointed out.
If we want to change anything here, i suggest we change WORD to something else, to try to avoid the problem that word could be a u16, u32, or even a u42, depending on where it is used.
Andrew
Michael S. Tsirkin
maintainerRe: [PATCH 1/3] virtio: dwords->qwords
Quoted 46 lines · Andrew Lunn
Quoted 45 lines · Michael S. Tsirkin
Quoted 6 lines · Andrew Lunn
Quoted 2 lines · Michael S. Tsirkin
A "word" is 16 bit. 64 bit integers like virtio uses are not dwords, they are actually qwords.
I'm having trouble with this....
Quoted 8 lines
This bit makes sense. 4x 16bits = 64 bits.
drivers/vhost/net.c MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" · line 72
Quoted 2 lines
drivers/vhost/net.c +1
-1-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS ] = { +static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS ] = {If this was u16, and
VIRTIO_FEATURES_QWORDSwas 4, which the Q would imply, than i would agree with what you are saying. But this is a u64 type. It is already a QWORD, and this is an array of two of them.I don't get what you are saying here.
It's an array of qwords andVIRTIO_FEATURES_QWORDStells you how many QWORDS are needed to fit all of them.This is how C arrays are declared.
Quoted 22 lines
I think the real issue here is not D vs Q, but WORD. We have a default meaning of a u16 for a word, especially in C. But that is not the actual definition of a word a computer scientist would use. Wikipedia has:
In computing, a word is any processor design's natural unit of data. A word is a fixed-sized datum handled as a unit by the instruction set or the hardware of the processor.
A word can be any size. In this context, virtio is not referring to the instruction set, but a protocol. Are all fields in this protocol u64? Hence word is u64? And this is an array of two words? That would make DWORD correct, it is two words.
If you want to change anything here, i would actually change WORD to something else, maybe FIELD?
And i could be wrong here, i've not looked at the actual protocol, so i've no idea if all fields in the protocol are u64. There are protocols like this, IPv6 uses u32, not octets, and the length field in the headers refer to the number of u32s in the header.
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Andrew
Virtio uses "dword" to mean "32 bits" in several places:
It also uses WORD to represent 32 bits:
That's not spec, that's linux driver. The spec is the source of truth.
Quoted 17 lines
void
vp_modern_get_driver_extended_features(structvirtio_pci_modern_device*mdev,u64 *features) { struct virtio_pci_common_cfg __iomem *cfg = mdev->common; int i; virtio_features_zero(features); for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { u64 cur; vp_iowrite32(i, &cfg->guest_feature_select); cur = vp_ioread32(&cfg->guest_feature); features[i >> 1] |= cur << (32 * (i & 1)); } }
Quoted 2 lines
And this is a function dealing features. So this seems to suggest a WORD is a u32, when dealing with features.
This is very recent with Paolo's patches/
That's exactly why my patches fix it.
Quoted 14 lines
A DWORD would thus be a
u64, making the current code correct.As i said, the problem here is WORD. It means different things to different people. And it even has different means to different parts of the virtio code, as you pointed out.
If we want to change anything here, i suggest we change WORD to something else, to try to avoid the problem that word could be a u16, u32, or even a u42, depending on where it is used.
Andrew
Re: [PATCH 1/3] virtio: dwords->qwords
Quoted 1 line
That's not spec, that's linux driver. The spec is the source of truth.
Right, lets follow this.
I'm looking at
https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html
Is that correct?
That document does not have a definition of word. However, what is interesting is section "4.2.2 MMIO Device Register Layout"
DeviceFeaturesSel 0x014
Device (host) features word selection.
Writing to this register selects a set of 32 device feature bits accessible by reading from DeviceFeatures.
and
DriverFeaturesSel 0x024
Activated (guest) features word selection
Writing to this register selects a set of 32 activated feature bits accessible by writing to DriverFeatures.
I would interpret this as meaning a feature word is a u32. Hence a DWORD is a u64, as the current code uses.
Andrew
Michael S. Tsirkin
maintainerRe: [PATCH 1/3] virtio: dwords->qwords
Quoted 22 lines · Andrew Lunn
Quoted 1 line
That's not spec, that's linux driver. The spec is the source of truth.
Right, lets follow this.
I'm looking at
https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html
Is that correct?
That document does not have a definition of word. However, what is interesting is section "4.2.2 MMIO Device Register Layout"
DeviceFeaturesSel
0x014Device (host) features word selection.
Writing to this register selects a set of 32 device feature bits accessible by reading from DeviceFeatures.and
DriverFeaturesSel
0x024
Quoted 7 lines
Activated (guest) features word selection
Writing to this register selects a set of 32 activated feature bits accessible by writing to DriverFeatures.I would interpret this as meaning a feature word is a u32. Hence a DWORD is a u64, as the current code uses.
Andrew
Hmm indeed.
At the same time, pci transport has:
u8 padding[2]; /* Pad to full dword. */
and i2c has:
The \field{padding} is used to pad to full dword.
both of which use dword to mean 32 bit.
This comes from PCI which also does not define word but uses it to mean 16 bit.
I don't have the problem changing everything to some other wording completely but "chunk" is uninformative, and more importantly does not give a clean way to refer to 2 chunks and 4 chunks.
Similarly, if we use "word" to mean 32 bit there is n clean way to refer to 16 bits which we use a lot.
using word as 16 bit has the advantage that you
can say byte/word/dword/qword and these do not
cause too much confusion.
So I am still inclined to align everything on pci terminology but interested to hear what alternative you suggest.
Signature · 1 line
MST
Re: [PATCH 1/3] virtio: dwords->qwords
Quoted 23 lines
Quoted 9 lines
DeviceFeaturesSel
0x014Device (host) features word selection.
Writing to this register selects a set of 32 device feature bits accessible by reading from DeviceFeatures.and
DriverFeaturesSel
0x024Quoted 7 lines
Activated (guest) features word selection
Writing to this register selects a set of 32 activated feature bits accessible by writing to DriverFeatures.I would interpret this as meaning a feature word is a u32. Hence a DWORD is a u64, as the current code uses.
Andrew
Hmm indeed.
At the same time, pci transport has:u8 padding[2]; /* Pad to full dword. */
Quoted 8 lines
and i2c has:
The \field{padding} is used to pad to full dword.
both of which use dword to mean 32 bit.
This comes from PCI which also does not define word but uses it to mean 16 bit.
Yes, reading the spec, you need to consider the context 'word' is used in. Maybe this is something which can be cleaned up, made uniform across the whole document?
Quoted 8 lines
I don't have the problem changing everything to some other wording completely but "chunk" is uninformative, and more importantly does not give a clean way to refer to 2 chunks and 4 chunks.
Similarly, if we use "word" to mean 32 bit there is n clean way to refer to 16 bits which we use a lot.
Quoted 6 lines
using word as 16 bit has the advantage that you
can say byte/word/dword/qword and these do not
cause too much confusion.So I am still inclined to align everything on pci terminology but interested to hear what alternative you suggest.
How about something simple:
#define VIRTIO_FEATURES_DU32WORDS 2
#define VIRTIO_FEATURES_U32WORDS (VIRTIO_FEATURES_D32WORDS * 2)
or, if the spec moves away from using 'word':
#define VIRTIO_FEATURES_U64S 2
#define VIRTIO_FEATURES_U32S (VIRTIO_FEATURES_U32S * 2)
The coding style says not to use Hungarian notation, but here it actually make sense, and avoids the ambiguity in the spec.
Andrew
Michael S. Tsirkin
maintainerRe: [PATCH 1/3] virtio: dwords->qwords
Quoted 27 lines · Andrew Lunn
Quoted 27 lines
Quoted 9 lines
DeviceFeaturesSel
0x014Device (host) features word selection.
Writing to this register selects a set of 32 device feature bits accessible by reading from DeviceFeatures.and
DriverFeaturesSel
0x024Quoted 7 lines
Activated (guest) features word selection
Writing to this register selects a set of 32 activated feature bits accessible by writing to DriverFeatures.I would interpret this as meaning a feature word is a u32. Hence a DWORD is a u64, as the current code uses.
Andrew
Hmm indeed.
At the same time, pci transport has:u8 padding[2]; /* Pad to full dword. */
and i2c has:
The \field{padding} is used to pad to full dword.
Quoted 8 lines
Quoted 4 lines
both of which use dword to mean 32 bit.
This comes from PCI which also does not define word but uses it to mean 16 bit.
Yes, reading the spec, you need to consider the context 'word' is used in. Maybe this is something which can be cleaned up, made uniform across the whole document?
Yes and thanks for bringing this to my attention.
So MMIO can be "features set selection"
And pci can be "pad to 32 bit".
Less work than defining "word".
Quoted 22 lines
Quoted 8 lines
I don't have the problem changing everything to some other wording completely but "chunk" is uninformative, and more importantly does not give a clean way to refer to 2 chunks and 4 chunks.
Similarly, if we use "word" to mean 32 bit there is n clean way to refer to 16 bits which we use a lot.Quoted 6 lines
using word as 16 bit has the advantage that you
can say byte/word/dword/qword and these do not
cause too much confusion.So I am still inclined to align everything on pci terminology but interested to hear what alternative you suggest.
How about something simple:
#define
VIRTIO_FEATURES_DU32WORDS2
#defineVIRTIO_FEATURES_U32WORDS(VIRTIO_FEATURES_D32WORDS* 2)or, if the spec moves away from using 'word':
Quoted 7 lines
#define
VIRTIO_FEATURES_U64S2
#defineVIRTIO_FEATURES_U32S(VIRTIO_FEATURES_U32S* 2)The coding style says not to use Hungarian notation, but here it actually make sense, and avoids the ambiguity in the spec.
Andrew
I mean we can just define number of bits. Open-code / 32 or / 64 as needed. Hmm?
Signature · 1 line
MST
Michael S. Tsirkin
maintainerPATCH 2/3 virtio: words->dwords
In reply to Michael S. TsirkinA "word" is 16 bit. 32 bit integers like virtio pci uses are not words, they are actually dwords. Fix up the macro name accordingly.
--- drivers/virtio/virtio_pci_modern_dev.c | 6 +++--- include/linux/virtio_features.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/virtio/virtio_pci_modern_dev.c +3 -3
@@ -401,7 +401,7 @@ void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev,int i;virtio_features_zero (features); -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) {u64 cur;vp_iowrite32 (i, &cfg->device_feature_select);
@@ -427,7 +427,7 @@ vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev,int i;virtio_features_zero (features); -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) {u64 cur;vp_iowrite32 (i, &cfg->guest_feature_select);
@@ -448,7 +448,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev,struct virtio_pci_common_cfg __iomem *cfg = mdev->common;int i; -for (i =0 ; i <VIRTIO_FEATURES_WORDS ; i++) { +for (i =0 ; i <VIRTIO_FEATURES_DWORDS ; i++) {u32 cur = features[i >>1 ] >> (32 * (i &1 ));vp_iowrite32 (i, &cfg->guest_feature_select);
include/linux/virtio_features.h +1 -1
@@ -6,7 +6,7 @@#define VIRTIO_FEATURES_QWORDS 2#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_QWORDS * 64) -#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_QWORDS * 2) +#define VIRTIO_FEATURES_DWORDS (VIRTIO_FEATURES_QWORDS * 2)#define VIRTIO_BIT (b) BIT_ULL((b) & 0x3f)#define VIRTIO_QWORD (b) ((b) >> 6)#define VIRTIO_DECLARE_FEATURES (name) \
Signature · 1 line
MST
Michael S. Tsirkin
maintainerPATCH 3/3 vhost: use checked versions of VIRTIO_BIT
In reply to Michael S. TsirkinThis adds compile-time checked versions of VIRTIO_BIT that set bits in low and high qword, respectively. Will prevent confusion when people set bits in the wrong qword.
--- drivers/vhost/net.c | 4 ++-- include/linux/virtio_features.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-)
drivers/vhost/net.c +2 -2
@@ -76,8 +76,8 @@ static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS] = { (1ULL <<VIRTIO_F_ACCESS_PLATFORM ) | (1ULL <<VIRTIO_F_RING_RESET ) | (1ULL <<VIRTIO_F_IN_ORDER ), -VIRTIO_BIT (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | - VIRTIO_BIT(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO), +VIRTIO_BIT_HI (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | + VIRTIO_BIT_HI(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO), }; enum {
include/linux/virtio_features.h +9 -0
@@ -9,6 +9,15 @@#define VIRTIO_FEATURES_DWORDS (VIRTIO_FEATURES_QWORDS * 2)#define VIRTIO_BIT (b) BIT_ULL((b) & 0x3f)#define VIRTIO_QWORD (b) ((b) >> 6) + +/* Get a given feature bit in a given qword. */ +#define VIRTIO_BIT_QWORD (bit, qword) \ + (BUILD_BUG_ON_ZERO(const_true(VIRTIO_QWORD(bit) != (qword))) + \ + BIT_ULL((bit) - 64 * (qword))) + +#define VIRTIO_BIT_LO (b) VIRTIO_BIT_QWORD(b, 0) +#define VIRTIO_BIT_HI (b) VIRTIO_BIT_QWORD(b, 1) +#define VIRTIO_DECLARE_FEATURES (name) \ union { \ u64 name; \
Signature · 1 line
MST
Re: [PATCH 3/3] vhost: use checked versions of VIRTIO_BIT
Quoted 16 lines · Michael S. Tsirkin
This adds compile-time checked versions of
VIRTIO_BITthat set bits in low and high qword, respectively. Will prevent confusion when people set bits in the wrong qword.Cc "Paolo Abeni" <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>--- drivers/vhost/net.c | 4 ++-- include/linux/virtio_features.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-)drivers/vhost/net.c +0
-0
drivers/vhost/net.c static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS] = { · line 80
Quoted 7 lines
drivers/vhost/net.c +2
-2@@ -76,8 +76,8 @@ static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS] = { (1ULL <<VIRTIO_F_ACCESS_PLATFORM ) | (1ULL <<VIRTIO_F_RING_RESET ) | (1ULL <<VIRTIO_F_IN_ORDER ), -VIRTIO_BIT (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | - VIRTIO_BIT(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO), +VIRTIO_BIT_HI (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | + VIRTIO_BIT_HI(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO),
How any bits in vhost_net_features are currently in use? How likely is it to go from 2x 64bit words to 3x 64 bit words? Rather than _LO, _HI, would _1ST, _2ND be better leaving it open for _3RD?
I would also be tempted to rename these macros to include _LO_ and _HI_ in them. VIRTIO_BIT_HI(VIRTIO_LO_F_IN_ORDER) is more likely to be spotted as wrong this way.
An alternative would be to convert to a linux bitmap, which is arbitrary length so you just use bit number and leave the implementation to map that to the correct offset in the underlying data structure.
Andrew
Michael S. Tsirkin
maintainerRe: [PATCH 3/3] vhost: use checked versions of VIRTIO_BIT
Quoted 12 lines · Andrew Lunn
Quoted 11 lines · Michael S. Tsirkin
This adds compile-time checked versions of
VIRTIO_BITthat set bits in low and high qword, respectively. Will prevent confusion when people set bits in the wrong qword.Cc "Paolo Abeni" <[email protected]>Signed-off-by Michael S. Tsirkin <[email protected]>--- drivers/vhost/net.c | 4 ++-- include/linux/virtio_features.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-)
Quoted 14 lines
drivers/vhost/net.c static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS] = { · line 80
Quoted 12 lines
drivers/vhost/net.c +2
-2@@ -76,8 +76,8 @@ static const u64 vhost_net_features[VIRTIO_FEATURES_QWORDS] = { (1ULL <<VIRTIO_F_ACCESS_PLATFORM ) | (1ULL <<VIRTIO_F_RING_RESET ) | (1ULL <<VIRTIO_F_IN_ORDER ), -VIRTIO_BIT (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | - VIRTIO_BIT(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO), +VIRTIO_BIT_HI (VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO ) | + VIRTIO_BIT_HI(VIRTIO_NET_F_HOST_UDP_TUNNEL_GSO),How any bits in
vhost_net_featuresare currently in use?
68
Quoted 2 lines
How likely is
it to go from 2x 64bit words to 3x 64 bit words?
Maybe.
Quoted 2 lines
Rather than
_LO,_HI,
would_1ST,_2NDbe better leaving it open for_3RD?
I can just open-code
VIRTIO_BIT_QWORD(VIRTIO_NET_F_GUEST_UDP_TUNNEL_GSO, 1)
Quoted 3 lines
I would also be tempted to rename these macros to include _LO_ and _HI_ in them.
VIRTIO_BIT_HI(VIRTIO_LO_F_IN_ORDER)is more likely to be spotted as wrong this way.
Hmm but with my macros compiler will warn so why uglify then?
Quoted 6 lines
An alternative would be to convert to a linux bitmap, which is arbitrary length so you just use bit number and leave the implementation to map that to the correct offset in the underlying data structure.
Andrew
Right but it's a bit more work as we then have to change all drivers. Not ruling this out, but this patchset is not aiming that high.
Signature · 1 line
MST