* [PATCH v2 0/4] virtio/virtio_test @ 2022-07-07 2:44 Guo Zhi 2022-07-07 2:44 ` [PATCH v2 1/4] virtio_test: kick vhost for a batch of descriptors Guo Zhi ` (3 more replies) 0 siblings, 4 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 2:44 UTC (permalink / raw) To: jasowang, mst; +Cc: eperezma, virtualization, linux-kernel, sgarzare, Guo Zhi Original virtio_test only use add one descriptor for each io event, thus code of descriptor chain and indirection have not been tested(one descriptor will not use indirect feature even indirect feature has been specified). In fact it would have not been possible for vhost_test to access to the indirect descriptor table, because it's impossible for virtio_ring.c to allocate it. This series using descriptor chain and enable indirection feature. And through gcov we find the code coverage has been improved(not high for virtio_ring.c because virtio_test only test split virtqueue): +------------+-------------+-------------+ | |virtio_test.c|virtio_ring.c| +------------+-------------+-------------+ | original | 72.32% | 24.71% | +------------+-------------+-------------+ | current | 75% | 28.05% | +------------+-------------+-------------+ Guo Zhi (4): virtio_test: kick vhost for a batch of descriptors virtio_test: move magic number in code as defined constant virtio_test: use random length scatterlists to test descriptor chain virtio_test: enable indirection feature tools/virtio/virtio_test.c | 86 ++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 22 deletions(-) -- 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 1/4] virtio_test: kick vhost for a batch of descriptors 2022-07-07 2:44 [PATCH v2 0/4] virtio/virtio_test Guo Zhi @ 2022-07-07 2:44 ` Guo Zhi 2022-07-07 2:44 ` [PATCH v2 2/4] virtio_test: move magic number in code as defined constant Guo Zhi ` (2 subsequent siblings) 3 siblings, 0 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 2:44 UTC (permalink / raw) To: jasowang, mst; +Cc: eperezma, virtualization, linux-kernel, sgarzare, Guo Zhi Only kick vhost when the batch finishes. Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> --- tools/virtio/virtio_test.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 23f142af5..95f78b311 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -208,11 +208,10 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, } ++started; - - if (unlikely(!virtqueue_kick(vq->vq))) { - r = -1; - break; - } + } + if (unlikely(!virtqueue_kick(vq->vq))) { + r = -1; + break; } if (started >= bufs) -- 2.17.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 2:44 [PATCH v2 0/4] virtio/virtio_test Guo Zhi 2022-07-07 2:44 ` [PATCH v2 1/4] virtio_test: kick vhost for a batch of descriptors Guo Zhi @ 2022-07-07 2:44 ` Guo Zhi 2022-07-07 5:09 ` Michael S. Tsirkin 2022-07-07 2:44 ` [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain Guo Zhi 2022-07-07 2:44 ` [PATCH v2 4/4] virtio_test: enable indirection feature Guo Zhi 3 siblings, 1 reply; 21+ messages in thread From: Guo Zhi @ 2022-07-07 2:44 UTC (permalink / raw) To: jasowang, mst; +Cc: eperezma, virtualization, linux-kernel, sgarzare, Guo Zhi We should avoid using magic numbers directly. Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> --- tools/virtio/virtio_test.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 95f78b311..1ecd64271 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -20,7 +20,10 @@ #include "../../drivers/vhost/test.h" #define RANDOM_BATCH -1 - +#define ALIGN 4096 +#define RINGSIZE 256 +#define TEST_BUF_NUM 0x100000 +#define BUF_SIZE 1024 /* Unused */ void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) if (info->vq) vring_del_virtqueue(info->vq); - memset(info->ring, 0, vring_size(num, 4096)); - vring_init(&info->vring, num, info->ring, 4096); + memset(info->ring, 0, vring_size(num, ALIGN)); + vring_init(&info->vring, num, info->ring, ALIGN); info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, false, vq_notify, vq_callback, "test"); assert(info->vq); @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) info->idx = dev->nvqs; info->kick = eventfd(0, EFD_NONBLOCK); info->call = eventfd(0, EFD_NONBLOCK); - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); assert(r >= 0); vq_reset(info, num, &dev->vdev); vhost_vq_setup(dev, info); @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) dev->vdev.features = features; INIT_LIST_HEAD(&dev->vdev.vqs); spin_lock_init(&dev->vdev.vqs_list_lock); - dev->buf_size = 1024; + dev->buf_size = BUF_SIZE; dev->buf = malloc(dev->buf_size); assert(dev->buf); dev->control = open("/dev/vhost-test", O_RDWR); @@ -396,7 +399,8 @@ int main(int argc, char **argv) done: vdev_info_init(&dev, features); - vq_info_add(&dev, 256); - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); + vq_info_add(&dev, RINGSIZE); + + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); return 0; } -- 2.17.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 2:44 ` [PATCH v2 2/4] virtio_test: move magic number in code as defined constant Guo Zhi @ 2022-07-07 5:09 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:09 UTC (permalink / raw) To: Guo Zhi; +Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: > We should avoid using magic numbers directly. Not necessarily. For repeated values - I guess. But this kind of thing: #define BUF_SIZE 1024 int buf_size = BUF_SIZE; brings no benefit IMHO. And this has cost - values are now removed from code. > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 95f78b311..1ecd64271 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -20,7 +20,10 @@ > #include "../../drivers/vhost/test.h" > > #define RANDOM_BATCH -1 > - > +#define ALIGN 4096 > +#define RINGSIZE 256 > +#define TEST_BUF_NUM 0x100000 > +#define BUF_SIZE 1024 > /* Unused */ > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) > if (info->vq) > vring_del_virtqueue(info->vq); > > - memset(info->ring, 0, vring_size(num, 4096)); > - vring_init(&info->vring, num, info->ring, 4096); > + memset(info->ring, 0, vring_size(num, ALIGN)); > + vring_init(&info->vring, num, info->ring, ALIGN); > info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, > false, vq_notify, vq_callback, "test"); > assert(info->vq); > @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) > info->idx = dev->nvqs; > info->kick = eventfd(0, EFD_NONBLOCK); > info->call = eventfd(0, EFD_NONBLOCK); > - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); > + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); > assert(r >= 0); > vq_reset(info, num, &dev->vdev); > vhost_vq_setup(dev, info); This is actually doing more than what commit log says. > @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > dev->vdev.features = features; > INIT_LIST_HEAD(&dev->vdev.vqs); > spin_lock_init(&dev->vdev.vqs_list_lock); > - dev->buf_size = 1024; > + dev->buf_size = BUF_SIZE; This seems to have zero added value. > dev->buf = malloc(dev->buf_size); > assert(dev->buf); > dev->control = open("/dev/vhost-test", O_RDWR); > @@ -396,7 +399,8 @@ int main(int argc, char **argv) > > done: > vdev_info_init(&dev, features); > - vq_info_add(&dev, 256); > - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); > + vq_info_add(&dev, RINGSIZE); > + > + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); > return 0; This replacement does not buy us anything either. > } > -- > 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant @ 2022-07-07 5:09 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:09 UTC (permalink / raw) To: Guo Zhi; +Cc: eperezma, linux-kernel, virtualization On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: > We should avoid using magic numbers directly. Not necessarily. For repeated values - I guess. But this kind of thing: #define BUF_SIZE 1024 int buf_size = BUF_SIZE; brings no benefit IMHO. And this has cost - values are now removed from code. > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 18 +++++++++++------- > 1 file changed, 11 insertions(+), 7 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 95f78b311..1ecd64271 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -20,7 +20,10 @@ > #include "../../drivers/vhost/test.h" > > #define RANDOM_BATCH -1 > - > +#define ALIGN 4096 > +#define RINGSIZE 256 > +#define TEST_BUF_NUM 0x100000 > +#define BUF_SIZE 1024 > /* Unused */ > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) > if (info->vq) > vring_del_virtqueue(info->vq); > > - memset(info->ring, 0, vring_size(num, 4096)); > - vring_init(&info->vring, num, info->ring, 4096); > + memset(info->ring, 0, vring_size(num, ALIGN)); > + vring_init(&info->vring, num, info->ring, ALIGN); > info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, > false, vq_notify, vq_callback, "test"); > assert(info->vq); > @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) > info->idx = dev->nvqs; > info->kick = eventfd(0, EFD_NONBLOCK); > info->call = eventfd(0, EFD_NONBLOCK); > - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); > + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); > assert(r >= 0); > vq_reset(info, num, &dev->vdev); > vhost_vq_setup(dev, info); This is actually doing more than what commit log says. > @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > dev->vdev.features = features; > INIT_LIST_HEAD(&dev->vdev.vqs); > spin_lock_init(&dev->vdev.vqs_list_lock); > - dev->buf_size = 1024; > + dev->buf_size = BUF_SIZE; This seems to have zero added value. > dev->buf = malloc(dev->buf_size); > assert(dev->buf); > dev->control = open("/dev/vhost-test", O_RDWR); > @@ -396,7 +399,8 @@ int main(int argc, char **argv) > > done: > vdev_info_init(&dev, features); > - vq_info_add(&dev, 256); > - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); > + vq_info_add(&dev, RINGSIZE); > + > + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); > return 0; This replacement does not buy us anything either. > } > -- > 2.17.1 _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 5:09 ` Michael S. Tsirkin (?) @ 2022-07-07 6:17 ` Guo Zhi 2022-07-07 7:36 ` Michael S. Tsirkin -1 siblings, 1 reply; 21+ messages in thread From: Guo Zhi @ 2022-07-07 6:17 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 13:09, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: >> We should avoid using magic numbers directly. > Not necessarily. For repeated values - I guess. > But this kind of thing: > > #define BUF_SIZE 1024 > int buf_size = BUF_SIZE; > > brings no benefit IMHO. > > And this has cost - values are now removed from code. Firstly, as a test, user will have to change the config to test virtio and vhost frequently. If these magic number are put together like these, change will be more easier. Secondly, many configs will be repeated, such as MAX_SG_FRAGS, even if some varibale only appear once, subsequent upgrade of virtio_test will use these variable in other place. For example, in this series of patch, patch 4/4 will use RINGSIZE to set INDIRECTS_BUF_SIZE. >> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> >> --- >> tools/virtio/virtio_test.c | 18 +++++++++++------- >> 1 file changed, 11 insertions(+), 7 deletions(-) >> >> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >> index 95f78b311..1ecd64271 100644 >> --- a/tools/virtio/virtio_test.c >> +++ b/tools/virtio/virtio_test.c >> @@ -20,7 +20,10 @@ >> #include "../../drivers/vhost/test.h" >> >> #define RANDOM_BATCH -1 >> - >> +#define ALIGN 4096 >> +#define RINGSIZE 256 >> +#define TEST_BUF_NUM 0x100000 >> +#define BUF_SIZE 1024 >> /* Unused */ >> void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; >> >> @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) >> if (info->vq) >> vring_del_virtqueue(info->vq); >> >> - memset(info->ring, 0, vring_size(num, 4096)); >> - vring_init(&info->vring, num, info->ring, 4096); >> + memset(info->ring, 0, vring_size(num, ALIGN)); >> + vring_init(&info->vring, num, info->ring, ALIGN); >> info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, >> false, vq_notify, vq_callback, "test"); >> assert(info->vq); >> @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) >> info->idx = dev->nvqs; >> info->kick = eventfd(0, EFD_NONBLOCK); >> info->call = eventfd(0, EFD_NONBLOCK); >> - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); >> + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); >> assert(r >= 0); >> vq_reset(info, num, &dev->vdev); >> vhost_vq_setup(dev, info); > This is actually doing more than what commit log says. > >> @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >> dev->vdev.features = features; >> INIT_LIST_HEAD(&dev->vdev.vqs); >> spin_lock_init(&dev->vdev.vqs_list_lock); >> - dev->buf_size = 1024; >> + dev->buf_size = BUF_SIZE; >> >> >> This seems to have zero added value. >> Since the reason above and other magic number have been set as a defined constant, change here for simplicity and consistency. >> dev->buf = malloc(dev->buf_size); >> assert(dev->buf); >> dev->control = open("/dev/vhost-test", O_RDWR); >> @@ -396,7 +399,8 @@ int main(int argc, char **argv) >> >> done: >> vdev_info_init(&dev, features); >> - vq_info_add(&dev, 256); >> - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); >> + vq_info_add(&dev, RINGSIZE); >> + >> + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); >> return 0; > > This replacement does not buy us anything either. RINGSIZE will be used in other place in subsequent modification. > >> } >> -- >> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 6:17 ` Guo Zhi @ 2022-07-07 7:36 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 7:36 UTC (permalink / raw) To: Guo Zhi; +Cc: eperezma, linux-kernel, virtualization On Thu, Jul 07, 2022 at 02:17:19PM +0800, Guo Zhi wrote: > On 2022/7/7 13:09, Michael S. Tsirkin wrote: > > On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: > > > We should avoid using magic numbers directly. > > Not necessarily. For repeated values - I guess. > > But this kind of thing: > > > > #define BUF_SIZE 1024 > > int buf_size = BUF_SIZE; > > > > brings no benefit IMHO. > > > > And this has cost - values are now removed from code. > > Firstly, as a test, user will have to change the config to test virtio and > vhost frequently. If these magic number are put together like these, change > will be more easier. If tweaking these is useful for users we should add a command line flags as opposed to asking users to tweak code. > Secondly, many configs will be repeated, such as MAX_SG_FRAGS, even if some > varibale only appear once, subsequent upgrade of virtio_test will use these > variable in other place. For example, in this series of patch, patch 4/4 > will use RINGSIZE to set INDIRECTS_BUF_SIZE. > > > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> Isn't there some way to use the size we get as 1st parameter of kmalloc? > > > --- > > > tools/virtio/virtio_test.c | 18 +++++++++++------- > > > 1 file changed, 11 insertions(+), 7 deletions(-) > > > > > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > > > index 95f78b311..1ecd64271 100644 > > > --- a/tools/virtio/virtio_test.c > > > +++ b/tools/virtio/virtio_test.c > > > @@ -20,7 +20,10 @@ > > > #include "../../drivers/vhost/test.h" > > > #define RANDOM_BATCH -1 > > > - > > > +#define ALIGN 4096 > > > +#define RINGSIZE 256 > > > +#define TEST_BUF_NUM 0x100000 > > > +#define BUF_SIZE 1024 > > > /* Unused */ > > > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > > @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) > > > if (info->vq) > > > vring_del_virtqueue(info->vq); > > > - memset(info->ring, 0, vring_size(num, 4096)); > > > - vring_init(&info->vring, num, info->ring, 4096); > > > + memset(info->ring, 0, vring_size(num, ALIGN)); > > > + vring_init(&info->vring, num, info->ring, ALIGN); > > > info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, > > > false, vq_notify, vq_callback, "test"); > > > assert(info->vq); > > > @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) > > > info->idx = dev->nvqs; > > > info->kick = eventfd(0, EFD_NONBLOCK); > > > info->call = eventfd(0, EFD_NONBLOCK); > > > - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); > > > + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); > > > assert(r >= 0); > > > vq_reset(info, num, &dev->vdev); > > > vhost_vq_setup(dev, info); > > This is actually doing more than what commit log says. > > > > > @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > dev->vdev.features = features; > > > INIT_LIST_HEAD(&dev->vdev.vqs); > > > spin_lock_init(&dev->vdev.vqs_list_lock); > > > - dev->buf_size = 1024; > > > + dev->buf_size = BUF_SIZE; > > > > > > > > > This seems to have zero added value. > > > > Since the reason above and other magic number have been set as a defined > constant, change here for simplicity and consistency. > > > dev->buf = malloc(dev->buf_size); > > > assert(dev->buf); > > > dev->control = open("/dev/vhost-test", O_RDWR); > > > @@ -396,7 +399,8 @@ int main(int argc, char **argv) > > > done: > > > vdev_info_init(&dev, features); > > > - vq_info_add(&dev, 256); > > > - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); > > > + vq_info_add(&dev, RINGSIZE); > > > + > > > + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); > > > return 0; > > > > This replacement does not buy us anything either. > RINGSIZE will be used in other place in subsequent modification. > > > > > } > > > -- > > > 2.17.1 > _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant @ 2022-07-07 7:36 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 7:36 UTC (permalink / raw) To: Guo Zhi; +Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On Thu, Jul 07, 2022 at 02:17:19PM +0800, Guo Zhi wrote: > On 2022/7/7 13:09, Michael S. Tsirkin wrote: > > On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: > > > We should avoid using magic numbers directly. > > Not necessarily. For repeated values - I guess. > > But this kind of thing: > > > > #define BUF_SIZE 1024 > > int buf_size = BUF_SIZE; > > > > brings no benefit IMHO. > > > > And this has cost - values are now removed from code. > > Firstly, as a test, user will have to change the config to test virtio and > vhost frequently. If these magic number are put together like these, change > will be more easier. If tweaking these is useful for users we should add a command line flags as opposed to asking users to tweak code. > Secondly, many configs will be repeated, such as MAX_SG_FRAGS, even if some > varibale only appear once, subsequent upgrade of virtio_test will use these > variable in other place. For example, in this series of patch, patch 4/4 > will use RINGSIZE to set INDIRECTS_BUF_SIZE. > > > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> Isn't there some way to use the size we get as 1st parameter of kmalloc? > > > --- > > > tools/virtio/virtio_test.c | 18 +++++++++++------- > > > 1 file changed, 11 insertions(+), 7 deletions(-) > > > > > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > > > index 95f78b311..1ecd64271 100644 > > > --- a/tools/virtio/virtio_test.c > > > +++ b/tools/virtio/virtio_test.c > > > @@ -20,7 +20,10 @@ > > > #include "../../drivers/vhost/test.h" > > > #define RANDOM_BATCH -1 > > > - > > > +#define ALIGN 4096 > > > +#define RINGSIZE 256 > > > +#define TEST_BUF_NUM 0x100000 > > > +#define BUF_SIZE 1024 > > > /* Unused */ > > > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > > @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) > > > if (info->vq) > > > vring_del_virtqueue(info->vq); > > > - memset(info->ring, 0, vring_size(num, 4096)); > > > - vring_init(&info->vring, num, info->ring, 4096); > > > + memset(info->ring, 0, vring_size(num, ALIGN)); > > > + vring_init(&info->vring, num, info->ring, ALIGN); > > > info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, > > > false, vq_notify, vq_callback, "test"); > > > assert(info->vq); > > > @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) > > > info->idx = dev->nvqs; > > > info->kick = eventfd(0, EFD_NONBLOCK); > > > info->call = eventfd(0, EFD_NONBLOCK); > > > - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); > > > + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); > > > assert(r >= 0); > > > vq_reset(info, num, &dev->vdev); > > > vhost_vq_setup(dev, info); > > This is actually doing more than what commit log says. > > > > > @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > dev->vdev.features = features; > > > INIT_LIST_HEAD(&dev->vdev.vqs); > > > spin_lock_init(&dev->vdev.vqs_list_lock); > > > - dev->buf_size = 1024; > > > + dev->buf_size = BUF_SIZE; > > > > > > > > > This seems to have zero added value. > > > > Since the reason above and other magic number have been set as a defined > constant, change here for simplicity and consistency. > > > dev->buf = malloc(dev->buf_size); > > > assert(dev->buf); > > > dev->control = open("/dev/vhost-test", O_RDWR); > > > @@ -396,7 +399,8 @@ int main(int argc, char **argv) > > > done: > > > vdev_info_init(&dev, features); > > > - vq_info_add(&dev, 256); > > > - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); > > > + vq_info_add(&dev, RINGSIZE); > > > + > > > + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); > > > return 0; > > > > This replacement does not buy us anything either. > RINGSIZE will be used in other place in subsequent modification. > > > > > } > > > -- > > > 2.17.1 > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 7:36 ` Michael S. Tsirkin (?) @ 2022-07-07 12:15 ` Guo Zhi -1 siblings, 0 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 12:15 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 15:36, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 02:17:19PM +0800, Guo Zhi wrote: >> On 2022/7/7 13:09, Michael S. Tsirkin wrote: >>> On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: >>>> We should avoid using magic numbers directly. >>> Not necessarily. For repeated values - I guess. >>> But this kind of thing: >>> >>> #define BUF_SIZE 1024 >>> int buf_size = BUF_SIZE; >>> >>> brings no benefit IMHO. >>> >>> And this has cost - values are now removed from code. >> Firstly, as a test, user will have to change the config to test virtio and >> vhost frequently. If these magic number are put together like these, change >> will be more easier. > If tweaking these is useful for users we should add a command line flags > as opposed to asking users to tweak code. > >> Secondly, many configs will be repeated, such as MAX_SG_FRAGS, even if some >> varibale only appear once, subsequent upgrade of virtio_test will use these >> variable in other place. For example, in this series of patch, patch 4/4 >> will use RINGSIZE to set INDIRECTS_BUF_SIZE. >> >>>> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > Isn't there some way to use the size we get as 1st parameter of kmalloc? __kmalloc_fake has also been used in other place(vringh_test.c). which also use it to force allocate a specified user addr. And it is actually hard to use 1st parameter of kmalloc to calculate the address of the target addr, which also impact vringh_test if the semantic of __kmalloc_fake changes. > >>>> --- >>>> tools/virtio/virtio_test.c | 18 +++++++++++------- >>>> 1 file changed, 11 insertions(+), 7 deletions(-) >>>> >>>> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >>>> index 95f78b311..1ecd64271 100644 >>>> --- a/tools/virtio/virtio_test.c >>>> +++ b/tools/virtio/virtio_test.c >>>> @@ -20,7 +20,10 @@ >>>> #include "../../drivers/vhost/test.h" >>>> #define RANDOM_BATCH -1 >>>> - >>>> +#define ALIGN 4096 >>>> +#define RINGSIZE 256 >>>> +#define TEST_BUF_NUM 0x100000 >>>> +#define BUF_SIZE 1024 >>>> /* Unused */ >>>> void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; >>>> @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) >>>> if (info->vq) >>>> vring_del_virtqueue(info->vq); >>>> - memset(info->ring, 0, vring_size(num, 4096)); >>>> - vring_init(&info->vring, num, info->ring, 4096); >>>> + memset(info->ring, 0, vring_size(num, ALIGN)); >>>> + vring_init(&info->vring, num, info->ring, ALIGN); >>>> info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, >>>> false, vq_notify, vq_callback, "test"); >>>> assert(info->vq); >>>> @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) >>>> info->idx = dev->nvqs; >>>> info->kick = eventfd(0, EFD_NONBLOCK); >>>> info->call = eventfd(0, EFD_NONBLOCK); >>>> - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); >>>> + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); >>>> assert(r >= 0); >>>> vq_reset(info, num, &dev->vdev); >>>> vhost_vq_setup(dev, info); >>> This is actually doing more than what commit log says. >>> >>>> @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >>>> dev->vdev.features = features; >>>> INIT_LIST_HEAD(&dev->vdev.vqs); >>>> spin_lock_init(&dev->vdev.vqs_list_lock); >>>> - dev->buf_size = 1024; >>>> + dev->buf_size = BUF_SIZE; >>>> >>>> >>>> This seems to have zero added value. >>>> >> Since the reason above and other magic number have been set as a defined >> constant, change here for simplicity and consistency. >>>> dev->buf = malloc(dev->buf_size); >>>> assert(dev->buf); >>>> dev->control = open("/dev/vhost-test", O_RDWR); >>>> @@ -396,7 +399,8 @@ int main(int argc, char **argv) >>>> done: >>>> vdev_info_init(&dev, features); >>>> - vq_info_add(&dev, 256); >>>> - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); >>>> + vq_info_add(&dev, RINGSIZE); >>>> + >>>> + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); >>>> return 0; >>> This replacement does not buy us anything either. >> RINGSIZE will be used in other place in subsequent modification. >>>> } >>>> -- >>>> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 2/4] virtio_test: move magic number in code as defined constant 2022-07-07 7:36 ` Michael S. Tsirkin (?) (?) @ 2022-07-07 12:19 ` Guo Zhi -1 siblings, 0 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 12:19 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 15:36, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 02:17:19PM +0800, Guo Zhi wrote: >> On 2022/7/7 13:09, Michael S. Tsirkin wrote: >>> On Thu, Jul 07, 2022 at 10:44:07AM +0800, Guo Zhi wrote: >>>> We should avoid using magic numbers directly. >>> Not necessarily. For repeated values - I guess. >>> But this kind of thing: >>> >>> #define BUF_SIZE 1024 >>> int buf_size = BUF_SIZE; >>> >>> brings no benefit IMHO. >>> >>> And this has cost - values are now removed from code. >> Firstly, as a test, user will have to change the config to test virtio and >> vhost frequently. If these magic number are put together like these, change >> will be more easier. > If tweaking these is useful for users we should add a command line flags > as opposed to asking users to tweak code. I think you suggestions are correct, I should not change that magic numbers which doesn't have relationship with my work. So in next version patch, I will stop changing these magic number to defined values. > >> Secondly, many configs will be repeated, such as MAX_SG_FRAGS, even if some >> varibale only appear once, subsequent upgrade of virtio_test will use these >> variable in other place. For example, in this series of patch, patch 4/4 >> will use RINGSIZE to set INDIRECTS_BUF_SIZE. >> >>>> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > Isn't there some way to use the size we get as 1st parameter of kmalloc? > >>>> --- >>>> tools/virtio/virtio_test.c | 18 +++++++++++------- >>>> 1 file changed, 11 insertions(+), 7 deletions(-) >>>> >>>> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >>>> index 95f78b311..1ecd64271 100644 >>>> --- a/tools/virtio/virtio_test.c >>>> +++ b/tools/virtio/virtio_test.c >>>> @@ -20,7 +20,10 @@ >>>> #include "../../drivers/vhost/test.h" >>>> #define RANDOM_BATCH -1 >>>> - >>>> +#define ALIGN 4096 >>>> +#define RINGSIZE 256 >>>> +#define TEST_BUF_NUM 0x100000 >>>> +#define BUF_SIZE 1024 >>>> /* Unused */ >>>> void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; >>>> @@ -100,8 +103,8 @@ static void vq_reset(struct vq_info *info, int num, struct virtio_device *vdev) >>>> if (info->vq) >>>> vring_del_virtqueue(info->vq); >>>> - memset(info->ring, 0, vring_size(num, 4096)); >>>> - vring_init(&info->vring, num, info->ring, 4096); >>>> + memset(info->ring, 0, vring_size(num, ALIGN)); >>>> + vring_init(&info->vring, num, info->ring, ALIGN); >>>> info->vq = __vring_new_virtqueue(info->idx, info->vring, vdev, true, >>>> false, vq_notify, vq_callback, "test"); >>>> assert(info->vq); >>>> @@ -115,7 +118,7 @@ static void vq_info_add(struct vdev_info *dev, int num) >>>> info->idx = dev->nvqs; >>>> info->kick = eventfd(0, EFD_NONBLOCK); >>>> info->call = eventfd(0, EFD_NONBLOCK); >>>> - r = posix_memalign(&info->ring, 4096, vring_size(num, 4096)); >>>> + r = posix_memalign(&info->ring, PAGE_SIZE, vring_size(num, ALIGN)); >>>> assert(r >= 0); >>>> vq_reset(info, num, &dev->vdev); >>>> vhost_vq_setup(dev, info); >>> This is actually doing more than what commit log says. >>> >>>> @@ -131,7 +134,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >>>> dev->vdev.features = features; >>>> INIT_LIST_HEAD(&dev->vdev.vqs); >>>> spin_lock_init(&dev->vdev.vqs_list_lock); >>>> - dev->buf_size = 1024; >>>> + dev->buf_size = BUF_SIZE; >>>> >>>> >>>> This seems to have zero added value. >>>> >> Since the reason above and other magic number have been set as a defined >> constant, change here for simplicity and consistency. >>>> dev->buf = malloc(dev->buf_size); >>>> assert(dev->buf); >>>> dev->control = open("/dev/vhost-test", O_RDWR); >>>> @@ -396,7 +399,8 @@ int main(int argc, char **argv) >>>> done: >>>> vdev_info_init(&dev, features); >>>> - vq_info_add(&dev, 256); >>>> - run_test(&dev, &dev.vqs[0], delayed, batch, reset, 0x100000); >>>> + vq_info_add(&dev, RINGSIZE); >>>> + >>>> + run_test(&dev, &dev.vqs[0], delayed, batch, reset, TEST_BUF_NUM); >>>> return 0; >>> This replacement does not buy us anything either. >> RINGSIZE will be used in other place in subsequent modification. >>>> } >>>> -- >>>> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain 2022-07-07 2:44 [PATCH v2 0/4] virtio/virtio_test Guo Zhi 2022-07-07 2:44 ` [PATCH v2 1/4] virtio_test: kick vhost for a batch of descriptors Guo Zhi 2022-07-07 2:44 ` [PATCH v2 2/4] virtio_test: move magic number in code as defined constant Guo Zhi @ 2022-07-07 2:44 ` Guo Zhi 2022-07-07 5:16 ` Michael S. Tsirkin 2022-07-07 2:44 ` [PATCH v2 4/4] virtio_test: enable indirection feature Guo Zhi 3 siblings, 1 reply; 21+ messages in thread From: Guo Zhi @ 2022-07-07 2:44 UTC (permalink / raw) To: jasowang, mst; +Cc: eperezma, virtualization, linux-kernel, sgarzare, Guo Zhi Prior implementation only use one descriptor for each io event, which does't test code of descriptor chain. More importantly, one descriptor will not use indirect feature even indirect feature is specified. Use random length scatterlists here to test descriptor chain. Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> --- tools/virtio/virtio_test.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 1ecd64271..363695b33 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -20,6 +20,7 @@ #include "../../drivers/vhost/test.h" #define RANDOM_BATCH -1 +#define MAX_SG_FRAGS 8UL #define ALIGN 4096 #define RINGSIZE 256 #define TEST_BUF_NUM 0x100000 @@ -172,7 +173,8 @@ static void wait_for_interrupt(struct vdev_info *dev) static void run_test(struct vdev_info *dev, struct vq_info *vq, bool delayed, int batch, int reset_n, int bufs) { - struct scatterlist sl; + struct scatterlist sg[MAX_SG_FRAGS]; + int sg_size = 0; long started = 0, completed = 0, next_reset = reset_n; long completed_before, started_before; int r, test = 1; @@ -197,8 +199,11 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, while (started < bufs && (started - completed) < batch) { - sg_init_one(&sl, dev->buf, dev->buf_size); - r = virtqueue_add_outbuf(vq->vq, &sl, 1, + sg_size = random() % (MAX_SG_FRAGS - 1) + 1; + sg_init_table(sg, sg_size); + for (int i = 0; i < sg_size; ++i) + sg_set_buf(&sg[i], dev->buf + i, 0x1); + r = virtqueue_add_outbuf(vq->vq, sg, sg_size, dev->buf + started, GFP_ATOMIC); if (unlikely(r != 0)) { -- 2.17.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain 2022-07-07 2:44 ` [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain Guo Zhi @ 2022-07-07 5:16 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:16 UTC (permalink / raw) To: Guo Zhi; +Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On Thu, Jul 07, 2022 at 10:44:08AM +0800, Guo Zhi wrote: > Prior implementation only use one descriptor for each io event, which > does't test code of descriptor chain. More importantly, one descriptor > will not use indirect feature even indirect feature is specified. Use > random length scatterlists here to test descriptor chain. > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 1ecd64271..363695b33 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -20,6 +20,7 @@ > #include "../../drivers/vhost/test.h" > > #define RANDOM_BATCH -1 > +#define MAX_SG_FRAGS 8UL > #define ALIGN 4096 > #define RINGSIZE 256 > #define TEST_BUF_NUM 0x100000 > @@ -172,7 +173,8 @@ static void wait_for_interrupt(struct vdev_info *dev) > static void run_test(struct vdev_info *dev, struct vq_info *vq, > bool delayed, int batch, int reset_n, int bufs) > { > - struct scatterlist sl; > + struct scatterlist sg[MAX_SG_FRAGS]; > + int sg_size = 0; > long started = 0, completed = 0, next_reset = reset_n; > long completed_before, started_before; > int r, test = 1; > @@ -197,8 +199,11 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > while (started < bufs && > (started - completed) < batch) { > - sg_init_one(&sl, dev->buf, dev->buf_size); > - r = virtqueue_add_outbuf(vq->vq, &sl, 1, > + sg_size = random() % (MAX_SG_FRAGS - 1) + 1; > + sg_init_table(sg, sg_size); > + for (int i = 0; i < sg_size; ++i) > + sg_set_buf(&sg[i], dev->buf + i, 0x1); > + r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > dev->buf + started, > GFP_ATOMIC); > if (unlikely(r != 0)) { random on data path is pretty expensive. I would suggest get an array size from user (and maybe a seed?) and pregenerate some numbers, then reuse. > -- > 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain @ 2022-07-07 5:16 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:16 UTC (permalink / raw) To: Guo Zhi; +Cc: eperezma, linux-kernel, virtualization On Thu, Jul 07, 2022 at 10:44:08AM +0800, Guo Zhi wrote: > Prior implementation only use one descriptor for each io event, which > does't test code of descriptor chain. More importantly, one descriptor > will not use indirect feature even indirect feature is specified. Use > random length scatterlists here to test descriptor chain. > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 11 ++++++++--- > 1 file changed, 8 insertions(+), 3 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 1ecd64271..363695b33 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -20,6 +20,7 @@ > #include "../../drivers/vhost/test.h" > > #define RANDOM_BATCH -1 > +#define MAX_SG_FRAGS 8UL > #define ALIGN 4096 > #define RINGSIZE 256 > #define TEST_BUF_NUM 0x100000 > @@ -172,7 +173,8 @@ static void wait_for_interrupt(struct vdev_info *dev) > static void run_test(struct vdev_info *dev, struct vq_info *vq, > bool delayed, int batch, int reset_n, int bufs) > { > - struct scatterlist sl; > + struct scatterlist sg[MAX_SG_FRAGS]; > + int sg_size = 0; > long started = 0, completed = 0, next_reset = reset_n; > long completed_before, started_before; > int r, test = 1; > @@ -197,8 +199,11 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > while (started < bufs && > (started - completed) < batch) { > - sg_init_one(&sl, dev->buf, dev->buf_size); > - r = virtqueue_add_outbuf(vq->vq, &sl, 1, > + sg_size = random() % (MAX_SG_FRAGS - 1) + 1; > + sg_init_table(sg, sg_size); > + for (int i = 0; i < sg_size; ++i) > + sg_set_buf(&sg[i], dev->buf + i, 0x1); > + r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > dev->buf + started, > GFP_ATOMIC); > if (unlikely(r != 0)) { random on data path is pretty expensive. I would suggest get an array size from user (and maybe a seed?) and pregenerate some numbers, then reuse. > -- > 2.17.1 _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain 2022-07-07 5:16 ` Michael S. Tsirkin (?) @ 2022-07-07 6:24 ` Guo Zhi -1 siblings, 0 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 6:24 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 13:16, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 10:44:08AM +0800, Guo Zhi wrote: >> Prior implementation only use one descriptor for each io event, which >> does't test code of descriptor chain. More importantly, one descriptor >> will not use indirect feature even indirect feature is specified. Use >> random length scatterlists here to test descriptor chain. >> >> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> >> --- >> tools/virtio/virtio_test.c | 11 ++++++++--- >> 1 file changed, 8 insertions(+), 3 deletions(-) >> >> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >> index 1ecd64271..363695b33 100644 >> --- a/tools/virtio/virtio_test.c >> +++ b/tools/virtio/virtio_test.c >> @@ -20,6 +20,7 @@ >> #include "../../drivers/vhost/test.h" >> >> #define RANDOM_BATCH -1 >> +#define MAX_SG_FRAGS 8UL >> #define ALIGN 4096 >> #define RINGSIZE 256 >> #define TEST_BUF_NUM 0x100000 >> @@ -172,7 +173,8 @@ static void wait_for_interrupt(struct vdev_info *dev) >> static void run_test(struct vdev_info *dev, struct vq_info *vq, >> bool delayed, int batch, int reset_n, int bufs) >> { >> - struct scatterlist sl; >> + struct scatterlist sg[MAX_SG_FRAGS]; >> + int sg_size = 0; >> long started = 0, completed = 0, next_reset = reset_n; >> long completed_before, started_before; >> int r, test = 1; >> @@ -197,8 +199,11 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >> >> while (started < bufs && >> (started - completed) < batch) { >> - sg_init_one(&sl, dev->buf, dev->buf_size); >> - r = virtqueue_add_outbuf(vq->vq, &sl, 1, >> + sg_size = random() % (MAX_SG_FRAGS - 1) + 1; >> + sg_init_table(sg, sg_size); >> + for (int i = 0; i < sg_size; ++i) >> + sg_set_buf(&sg[i], dev->buf + i, 0x1); >> + r = virtqueue_add_outbuf(vq->vq, sg, sg_size, >> dev->buf + started, >> GFP_ATOMIC); >> if (unlikely(r != 0)) { > random on data path is pretty expensive. > I would suggest get an array size from user (and maybe a seed?) and > pregenerate some numbers, then reuse. SGTM, I will prepare a random number array before add outbuf begin. > >> -- >> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 4/4] virtio_test: enable indirection feature 2022-07-07 2:44 [PATCH v2 0/4] virtio/virtio_test Guo Zhi ` (2 preceding siblings ...) 2022-07-07 2:44 ` [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain Guo Zhi @ 2022-07-07 2:44 ` Guo Zhi 2022-07-07 4:59 ` Michael S. Tsirkin 3 siblings, 1 reply; 21+ messages in thread From: Guo Zhi @ 2022-07-07 2:44 UTC (permalink / raw) To: jasowang, mst; +Cc: eperezma, virtualization, linux-kernel, sgarzare, Guo Zhi Prior implementation don't use indirection feature because there is only one descriptor for every io event, actually prior implementation don't support indirection because vhost can't translate and find the indirect descriptors. This commit enable virtio_test malloc indirect descriptors in a indirect buffer and map this buffer to vhost, thus resolve this problem. Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> --- tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index 363695b33..dca408a5c 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c @@ -25,7 +25,7 @@ #define RINGSIZE 256 #define TEST_BUF_NUM 0x100000 #define BUF_SIZE 1024 -/* Unused */ +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; struct vq_info { @@ -47,6 +47,8 @@ struct vdev_info { int nvqs; void *buf; size_t buf_size; + void *indirects; + size_t indirects_size; struct vhost_memory *mem; }; @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) static void vdev_info_init(struct vdev_info* dev, unsigned long long features) { int r; + int nregions = 2; + memset(dev, 0, sizeof *dev); dev->vdev.features = features; INIT_LIST_HEAD(&dev->vdev.vqs); @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) dev->buf_size = BUF_SIZE; dev->buf = malloc(dev->buf_size); assert(dev->buf); - dev->control = open("/dev/vhost-test", O_RDWR); + dev->indirects_size = INDIRECTS_SIZE; + dev->indirects = malloc(dev->indirects_size); + assert(dev->indirects); + dev->control = open("/dev/vhost-test", O_RDWR); assert(dev->control >= 0); r = ioctl(dev->control, VHOST_SET_OWNER, NULL); assert(r >= 0); dev->mem = malloc(offsetof(struct vhost_memory, regions) + - sizeof dev->mem->regions[0]); + (sizeof(dev->mem->regions[0])) * nregions); assert(dev->mem); memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + - sizeof dev->mem->regions[0]); - dev->mem->nregions = 1; + (sizeof(dev->mem->regions[0])) * nregions); + dev->mem->nregions = nregions; dev->mem->regions[0].guest_phys_addr = (long)dev->buf; dev->mem->regions[0].userspace_addr = (long)dev->buf; dev->mem->regions[0].memory_size = dev->buf_size; + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; + dev->mem->regions[1].userspace_addr = (long)dev->indirects; + dev->mem->regions[1].memory_size = dev->indirects_size; r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); assert(r >= 0); } @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) } } +static int test_virtqueue_add_outbuf(struct virtqueue *vq, + struct scatterlist *sg, unsigned int num, + void *data, void *indirects) +{ + int r; + + __kmalloc_fake = indirects; + r = virtqueue_add_outbuf(vq, sg, num, data, + GFP_ATOMIC); + __kmalloc_fake = NULL; + return r; +} + static void run_test(struct vdev_info *dev, struct vq_info *vq, bool delayed, int batch, int reset_n, int bufs) { @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, unsigned len; long long spurious = 0; const bool random_batch = batch == RANDOM_BATCH; + void *indirects; r = ioctl(dev->control, VHOST_TEST_RUN, &test); assert(r >= 0); @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, next_reset = INT_MAX; } + /* Don't kfree indirects. */ + __kfree_ignore_start = dev->indirects; + __kfree_ignore_end = dev->indirects + dev->indirects_size; + for (;;) { virtqueue_disable_cb(vq->vq); completed_before = completed; started_before = started; + indirects = dev->indirects; do { const bool reset = completed > next_reset; if (random_batch) @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, sg_init_table(sg, sg_size); for (int i = 0; i < sg_size; ++i) sg_set_buf(&sg[i], dev->buf + i, 0x1); - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, - dev->buf + started, - GFP_ATOMIC); + + // use indirects buffer repeatedly + if (indirects + sg_size * sizeof(struct vring_desc) > + dev->indirects + dev->indirects_size) + indirects = dev->indirects; + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, + dev->buf + started, indirects); if (unlikely(r != 0)) { if (r == -ENOSPC && started > started_before) @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, } ++started; + indirects += sg_size * sizeof(struct vring_desc); } if (unlikely(!virtqueue_kick(vq->vq))) { r = -1; -- 2.17.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature 2022-07-07 2:44 ` [PATCH v2 4/4] virtio_test: enable indirection feature Guo Zhi @ 2022-07-07 4:59 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 4:59 UTC (permalink / raw) To: Guo Zhi; +Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: > Prior implementation don't use indirection feature because there is only > one descriptor for every io event, actually prior implementation don't > support indirection because vhost can't translate and find the indirect > descriptors. This commit enable virtio_test malloc indirect descriptors > in a indirect buffer and map this buffer to vhost, thus resolve this > problem. > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ > 1 file changed, 42 insertions(+), 8 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 363695b33..dca408a5c 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -25,7 +25,7 @@ > #define RINGSIZE 256 > #define TEST_BUF_NUM 0x100000 > #define BUF_SIZE 1024 > -/* Unused */ > +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > struct vq_info { > @@ -47,6 +47,8 @@ struct vdev_info { > int nvqs; > void *buf; > size_t buf_size; > + void *indirects; > + size_t indirects_size; What are these exactly? > struct vhost_memory *mem; > }; > > @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) > static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > { > int r; > + int nregions = 2; > + > memset(dev, 0, sizeof *dev); > dev->vdev.features = features; > INIT_LIST_HEAD(&dev->vdev.vqs); > @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > dev->buf_size = BUF_SIZE; > dev->buf = malloc(dev->buf_size); > assert(dev->buf); > - dev->control = open("/dev/vhost-test", O_RDWR); > + dev->indirects_size = INDIRECTS_SIZE; > + dev->indirects = malloc(dev->indirects_size); > + assert(dev->indirects); > + dev->control = open("/dev/vhost-test", O_RDWR); > assert(dev->control >= 0); > r = ioctl(dev->control, VHOST_SET_OWNER, NULL); > assert(r >= 0); > dev->mem = malloc(offsetof(struct vhost_memory, regions) + > - sizeof dev->mem->regions[0]); > + (sizeof(dev->mem->regions[0])) * nregions); > assert(dev->mem); > memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + > - sizeof dev->mem->regions[0]); > - dev->mem->nregions = 1; > + (sizeof(dev->mem->regions[0])) * nregions); > + dev->mem->nregions = nregions; > dev->mem->regions[0].guest_phys_addr = (long)dev->buf; > dev->mem->regions[0].userspace_addr = (long)dev->buf; > dev->mem->regions[0].memory_size = dev->buf_size; > + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; > + dev->mem->regions[1].userspace_addr = (long)dev->indirects; > + dev->mem->regions[1].memory_size = dev->indirects_size; > r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); > assert(r >= 0); > } > @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) > } > } > > +static int test_virtqueue_add_outbuf(struct virtqueue *vq, > + struct scatterlist *sg, unsigned int num, > + void *data, void *indirects) > +{ > + int r; > + > + __kmalloc_fake = indirects; > + r = virtqueue_add_outbuf(vq, sg, num, data, > + GFP_ATOMIC); > + __kmalloc_fake = NULL; > + return r; > +} > + Quite a hack. Please add comments with documentation. Also - no way to avoid hacks? > static void run_test(struct vdev_info *dev, struct vq_info *vq, > bool delayed, int batch, int reset_n, int bufs) > { > @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > unsigned len; > long long spurious = 0; > const bool random_batch = batch == RANDOM_BATCH; > + void *indirects; > > r = ioctl(dev->control, VHOST_TEST_RUN, &test); > assert(r >= 0); > @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > next_reset = INT_MAX; > } > > + /* Don't kfree indirects. */ > + __kfree_ignore_start = dev->indirects; > + __kfree_ignore_end = dev->indirects + dev->indirects_size; > + > for (;;) { > virtqueue_disable_cb(vq->vq); > completed_before = completed; > started_before = started; > + indirects = dev->indirects; > do { > const bool reset = completed > next_reset; > if (random_batch) > @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > sg_init_table(sg, sg_size); > for (int i = 0; i < sg_size; ++i) > sg_set_buf(&sg[i], dev->buf + i, 0x1); > - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > - dev->buf + started, > - GFP_ATOMIC); > + > + // use indirects buffer repeatedly C style comments please. > + if (indirects + sg_size * sizeof(struct vring_desc) > > + dev->indirects + dev->indirects_size) > + indirects = dev->indirects; > + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, > + dev->buf + started, indirects); > if (unlikely(r != 0)) { > if (r == -ENOSPC && > started > started_before) > @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > } > > ++started; > + indirects += sg_size * sizeof(struct vring_desc); > } > if (unlikely(!virtqueue_kick(vq->vq))) { > r = -1; > -- > 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature @ 2022-07-07 4:59 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 4:59 UTC (permalink / raw) To: Guo Zhi; +Cc: eperezma, linux-kernel, virtualization On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: > Prior implementation don't use indirection feature because there is only > one descriptor for every io event, actually prior implementation don't > support indirection because vhost can't translate and find the indirect > descriptors. This commit enable virtio_test malloc indirect descriptors > in a indirect buffer and map this buffer to vhost, thus resolve this > problem. > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > --- > tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ > 1 file changed, 42 insertions(+), 8 deletions(-) > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > index 363695b33..dca408a5c 100644 > --- a/tools/virtio/virtio_test.c > +++ b/tools/virtio/virtio_test.c > @@ -25,7 +25,7 @@ > #define RINGSIZE 256 > #define TEST_BUF_NUM 0x100000 > #define BUF_SIZE 1024 > -/* Unused */ > +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > struct vq_info { > @@ -47,6 +47,8 @@ struct vdev_info { > int nvqs; > void *buf; > size_t buf_size; > + void *indirects; > + size_t indirects_size; What are these exactly? > struct vhost_memory *mem; > }; > > @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) > static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > { > int r; > + int nregions = 2; > + > memset(dev, 0, sizeof *dev); > dev->vdev.features = features; > INIT_LIST_HEAD(&dev->vdev.vqs); > @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > dev->buf_size = BUF_SIZE; > dev->buf = malloc(dev->buf_size); > assert(dev->buf); > - dev->control = open("/dev/vhost-test", O_RDWR); > + dev->indirects_size = INDIRECTS_SIZE; > + dev->indirects = malloc(dev->indirects_size); > + assert(dev->indirects); > + dev->control = open("/dev/vhost-test", O_RDWR); > assert(dev->control >= 0); > r = ioctl(dev->control, VHOST_SET_OWNER, NULL); > assert(r >= 0); > dev->mem = malloc(offsetof(struct vhost_memory, regions) + > - sizeof dev->mem->regions[0]); > + (sizeof(dev->mem->regions[0])) * nregions); > assert(dev->mem); > memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + > - sizeof dev->mem->regions[0]); > - dev->mem->nregions = 1; > + (sizeof(dev->mem->regions[0])) * nregions); > + dev->mem->nregions = nregions; > dev->mem->regions[0].guest_phys_addr = (long)dev->buf; > dev->mem->regions[0].userspace_addr = (long)dev->buf; > dev->mem->regions[0].memory_size = dev->buf_size; > + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; > + dev->mem->regions[1].userspace_addr = (long)dev->indirects; > + dev->mem->regions[1].memory_size = dev->indirects_size; > r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); > assert(r >= 0); > } > @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) > } > } > > +static int test_virtqueue_add_outbuf(struct virtqueue *vq, > + struct scatterlist *sg, unsigned int num, > + void *data, void *indirects) > +{ > + int r; > + > + __kmalloc_fake = indirects; > + r = virtqueue_add_outbuf(vq, sg, num, data, > + GFP_ATOMIC); > + __kmalloc_fake = NULL; > + return r; > +} > + Quite a hack. Please add comments with documentation. Also - no way to avoid hacks? > static void run_test(struct vdev_info *dev, struct vq_info *vq, > bool delayed, int batch, int reset_n, int bufs) > { > @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > unsigned len; > long long spurious = 0; > const bool random_batch = batch == RANDOM_BATCH; > + void *indirects; > > r = ioctl(dev->control, VHOST_TEST_RUN, &test); > assert(r >= 0); > @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > next_reset = INT_MAX; > } > > + /* Don't kfree indirects. */ > + __kfree_ignore_start = dev->indirects; > + __kfree_ignore_end = dev->indirects + dev->indirects_size; > + > for (;;) { > virtqueue_disable_cb(vq->vq); > completed_before = completed; > started_before = started; > + indirects = dev->indirects; > do { > const bool reset = completed > next_reset; > if (random_batch) > @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > sg_init_table(sg, sg_size); > for (int i = 0; i < sg_size; ++i) > sg_set_buf(&sg[i], dev->buf + i, 0x1); > - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > - dev->buf + started, > - GFP_ATOMIC); > + > + // use indirects buffer repeatedly C style comments please. > + if (indirects + sg_size * sizeof(struct vring_desc) > > + dev->indirects + dev->indirects_size) > + indirects = dev->indirects; > + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, > + dev->buf + started, indirects); > if (unlikely(r != 0)) { > if (r == -ENOSPC && > started > started_before) > @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > } > > ++started; > + indirects += sg_size * sizeof(struct vring_desc); > } > if (unlikely(!virtqueue_kick(vq->vq))) { > r = -1; > -- > 2.17.1 _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature 2022-07-07 4:59 ` Michael S. Tsirkin (?) @ 2022-07-07 5:56 ` Guo Zhi 2022-07-07 5:59 ` Michael S. Tsirkin -1 siblings, 1 reply; 21+ messages in thread From: Guo Zhi @ 2022-07-07 5:56 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 12:59, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: >> Prior implementation don't use indirection feature because there is only >> one descriptor for every io event, actually prior implementation don't >> support indirection because vhost can't translate and find the indirect >> descriptors. This commit enable virtio_test malloc indirect descriptors >> in a indirect buffer and map this buffer to vhost, thus resolve this >> problem. >> >> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> >> --- >> tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ >> 1 file changed, 42 insertions(+), 8 deletions(-) >> >> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >> index 363695b33..dca408a5c 100644 >> --- a/tools/virtio/virtio_test.c >> +++ b/tools/virtio/virtio_test.c >> @@ -25,7 +25,7 @@ >> #define RINGSIZE 256 >> #define TEST_BUF_NUM 0x100000 >> #define BUF_SIZE 1024 >> -/* Unused */ >> +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) >> void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; >> >> struct vq_info { >> @@ -47,6 +47,8 @@ struct vdev_info { >> int nvqs; >> void *buf; >> size_t buf_size; >> + void *indirects; >> + size_t indirects_size; > What are these exactly? The buffer is used to put indirect descriptors, and the buffer will be added in the vhost iotlb through VHOST_SET_MEM_TABLE, so that vhost can translate the descriptors in user mode correctly. > >> struct vhost_memory *mem; >> }; >> >> @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) >> static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >> { >> int r; >> + int nregions = 2; >> + >> memset(dev, 0, sizeof *dev); >> dev->vdev.features = features; >> INIT_LIST_HEAD(&dev->vdev.vqs); >> @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >> dev->buf_size = BUF_SIZE; >> dev->buf = malloc(dev->buf_size); >> assert(dev->buf); >> - dev->control = open("/dev/vhost-test", O_RDWR); >> + dev->indirects_size = INDIRECTS_SIZE; >> + dev->indirects = malloc(dev->indirects_size); >> + assert(dev->indirects); >> + dev->control = open("/dev/vhost-test", O_RDWR); >> assert(dev->control >= 0); >> r = ioctl(dev->control, VHOST_SET_OWNER, NULL); >> assert(r >= 0); >> dev->mem = malloc(offsetof(struct vhost_memory, regions) + >> - sizeof dev->mem->regions[0]); >> + (sizeof(dev->mem->regions[0])) * nregions); >> assert(dev->mem); >> memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + >> - sizeof dev->mem->regions[0]); >> - dev->mem->nregions = 1; >> + (sizeof(dev->mem->regions[0])) * nregions); >> + dev->mem->nregions = nregions; >> dev->mem->regions[0].guest_phys_addr = (long)dev->buf; >> dev->mem->regions[0].userspace_addr = (long)dev->buf; >> dev->mem->regions[0].memory_size = dev->buf_size; >> + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; >> + dev->mem->regions[1].userspace_addr = (long)dev->indirects; >> + dev->mem->regions[1].memory_size = dev->indirects_size; >> r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); >> assert(r >= 0); >> } >> @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) >> } >> } >> >> +static int test_virtqueue_add_outbuf(struct virtqueue *vq, >> + struct scatterlist *sg, unsigned int num, >> + void *data, void *indirects) >> +{ >> + int r; >> + >> + __kmalloc_fake = indirects; >> + r = virtqueue_add_outbuf(vq, sg, num, data, >> + GFP_ATOMIC); >> + __kmalloc_fake = NULL; >> + return r; >> +} >> + > Quite a hack. Please add comments with documentation. Also - no way to > avoid hacks? The __kmalloc_fake is refered from vringh_test. If not using __kmalloc_fake here, the vhost doesn't know how to translate the indirects descriptors(user address). We may could register a single region as large as the whole virtual space in the vhost iotlb using 1:1 mapping. But since they are tests, IMHO, better here to use VHOST_SET_MEM_TABLE with more regions. > >> static void run_test(struct vdev_info *dev, struct vq_info *vq, >> bool delayed, int batch, int reset_n, int bufs) >> { >> @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >> unsigned len; >> long long spurious = 0; >> const bool random_batch = batch == RANDOM_BATCH; >> + void *indirects; >> >> r = ioctl(dev->control, VHOST_TEST_RUN, &test); >> assert(r >= 0); >> @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >> next_reset = INT_MAX; >> } >> >> + /* Don't kfree indirects. */ >> + __kfree_ignore_start = dev->indirects; >> + __kfree_ignore_end = dev->indirects + dev->indirects_size; >> + >> for (;;) { >> virtqueue_disable_cb(vq->vq); >> completed_before = completed; >> started_before = started; >> + indirects = dev->indirects; >> do { >> const bool reset = completed > next_reset; >> if (random_batch) >> @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >> sg_init_table(sg, sg_size); >> for (int i = 0; i < sg_size; ++i) >> sg_set_buf(&sg[i], dev->buf + i, 0x1); >> - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, >> - dev->buf + started, >> - GFP_ATOMIC); >> + >> + // use indirects buffer repeatedly > > C style comments please. It will be modified. > >> + if (indirects + sg_size * sizeof(struct vring_desc) > >> + dev->indirects + dev->indirects_size) >> + indirects = dev->indirects; >> + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, >> + dev->buf + started, indirects); >> if (unlikely(r != 0)) { >> if (r == -ENOSPC && >> started > started_before) >> @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >> } >> >> ++started; >> + indirects += sg_size * sizeof(struct vring_desc); >> } >> if (unlikely(!virtqueue_kick(vq->vq))) { >> r = -1; >> -- >> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature 2022-07-07 5:56 ` Guo Zhi @ 2022-07-07 5:59 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:59 UTC (permalink / raw) To: Guo Zhi; +Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On Thu, Jul 07, 2022 at 01:56:37PM +0800, Guo Zhi wrote: > On 2022/7/7 12:59, Michael S. Tsirkin wrote: > > On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: > > > Prior implementation don't use indirection feature because there is only > > > one descriptor for every io event, actually prior implementation don't > > > support indirection because vhost can't translate and find the indirect > > > descriptors. This commit enable virtio_test malloc indirect descriptors > > > in a indirect buffer and map this buffer to vhost, thus resolve this > > > problem. > > > > > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > > > --- > > > tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ > > > 1 file changed, 42 insertions(+), 8 deletions(-) > > > > > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > > > index 363695b33..dca408a5c 100644 > > > --- a/tools/virtio/virtio_test.c > > > +++ b/tools/virtio/virtio_test.c > > > @@ -25,7 +25,7 @@ > > > #define RINGSIZE 256 > > > #define TEST_BUF_NUM 0x100000 > > > #define BUF_SIZE 1024 > > > -/* Unused */ > > > +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) > > > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > > struct vq_info { > > > @@ -47,6 +47,8 @@ struct vdev_info { > > > int nvqs; > > > void *buf; > > > size_t buf_size; > > > + void *indirects; > > > + size_t indirects_size; > > What are these exactly? > The buffer is used to put indirect descriptors, and the buffer will be added > in the vhost iotlb through VHOST_SET_MEM_TABLE, so that vhost can translate > the descriptors in user mode correctly. Pls come up with a better name. indirect_buf and indirect_buf_size? And add a comment. > > > > > struct vhost_memory *mem; > > > }; > > > @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) > > > static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > { > > > int r; > > > + int nregions = 2; > > > + > > > memset(dev, 0, sizeof *dev); > > > dev->vdev.features = features; > > > INIT_LIST_HEAD(&dev->vdev.vqs); > > > @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > dev->buf_size = BUF_SIZE; > > > dev->buf = malloc(dev->buf_size); > > > assert(dev->buf); > > > - dev->control = open("/dev/vhost-test", O_RDWR); > > > + dev->indirects_size = INDIRECTS_SIZE; > > > + dev->indirects = malloc(dev->indirects_size); > > > + assert(dev->indirects); > > > + dev->control = open("/dev/vhost-test", O_RDWR); > > > assert(dev->control >= 0); > > > r = ioctl(dev->control, VHOST_SET_OWNER, NULL); > > > assert(r >= 0); > > > dev->mem = malloc(offsetof(struct vhost_memory, regions) + > > > - sizeof dev->mem->regions[0]); > > > + (sizeof(dev->mem->regions[0])) * nregions); > > > assert(dev->mem); > > > memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + > > > - sizeof dev->mem->regions[0]); > > > - dev->mem->nregions = 1; > > > + (sizeof(dev->mem->regions[0])) * nregions); > > > + dev->mem->nregions = nregions; > > > dev->mem->regions[0].guest_phys_addr = (long)dev->buf; > > > dev->mem->regions[0].userspace_addr = (long)dev->buf; > > > dev->mem->regions[0].memory_size = dev->buf_size; > > > + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; > > > + dev->mem->regions[1].userspace_addr = (long)dev->indirects; > > > + dev->mem->regions[1].memory_size = dev->indirects_size; > > > r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); > > > assert(r >= 0); > > > } > > > @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) > > > } > > > } > > > +static int test_virtqueue_add_outbuf(struct virtqueue *vq, > > > + struct scatterlist *sg, unsigned int num, > > > + void *data, void *indirects) > > > +{ > > > + int r; > > > + > > > + __kmalloc_fake = indirects; > > > + r = virtqueue_add_outbuf(vq, sg, num, data, > > > + GFP_ATOMIC); > > > + __kmalloc_fake = NULL; > > > + return r; > > > +} > > > + > > Quite a hack. Please add comments with documentation. Also - no way to > > avoid hacks? > > The __kmalloc_fake is refered from vringh_test. > > If not using __kmalloc_fake here, the vhost doesn't know how to translate > the indirects descriptors(user address). > > We may could register a single region as large as the whole virtual space in > the vhost iotlb using 1:1 mapping. > > But since they are tests, IMHO, better here to use VHOST_SET_MEM_TABLE with > more regions. But why do we need to do this on each buffer add? > > > > > static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > bool delayed, int batch, int reset_n, int bufs) > > > { > > > @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > unsigned len; > > > long long spurious = 0; > > > const bool random_batch = batch == RANDOM_BATCH; > > > + void *indirects; > > > r = ioctl(dev->control, VHOST_TEST_RUN, &test); > > > assert(r >= 0); > > > @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > next_reset = INT_MAX; > > > } > > > + /* Don't kfree indirects. */ > > > + __kfree_ignore_start = dev->indirects; > > > + __kfree_ignore_end = dev->indirects + dev->indirects_size; > > > + > > > for (;;) { > > > virtqueue_disable_cb(vq->vq); > > > completed_before = completed; > > > started_before = started; > > > + indirects = dev->indirects; > > > do { > > > const bool reset = completed > next_reset; > > > if (random_batch) > > > @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > sg_init_table(sg, sg_size); > > > for (int i = 0; i < sg_size; ++i) > > > sg_set_buf(&sg[i], dev->buf + i, 0x1); > > > - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > > > - dev->buf + started, > > > - GFP_ATOMIC); > > > + > > > + // use indirects buffer repeatedly > > > > C style comments please. > It will be modified. > > > > > + if (indirects + sg_size * sizeof(struct vring_desc) > > > > + dev->indirects + dev->indirects_size) > > > + indirects = dev->indirects; > > > + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, > > > + dev->buf + started, indirects); > > > if (unlikely(r != 0)) { > > > if (r == -ENOSPC && > > > started > started_before) > > > @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > } > > > ++started; > > > + indirects += sg_size * sizeof(struct vring_desc); > > > } > > > if (unlikely(!virtqueue_kick(vq->vq))) { > > > r = -1; > > > -- > > > 2.17.1 > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature @ 2022-07-07 5:59 ` Michael S. Tsirkin 0 siblings, 0 replies; 21+ messages in thread From: Michael S. Tsirkin @ 2022-07-07 5:59 UTC (permalink / raw) To: Guo Zhi; +Cc: eperezma, linux-kernel, virtualization On Thu, Jul 07, 2022 at 01:56:37PM +0800, Guo Zhi wrote: > On 2022/7/7 12:59, Michael S. Tsirkin wrote: > > On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: > > > Prior implementation don't use indirection feature because there is only > > > one descriptor for every io event, actually prior implementation don't > > > support indirection because vhost can't translate and find the indirect > > > descriptors. This commit enable virtio_test malloc indirect descriptors > > > in a indirect buffer and map this buffer to vhost, thus resolve this > > > problem. > > > > > > Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> > > > --- > > > tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ > > > 1 file changed, 42 insertions(+), 8 deletions(-) > > > > > > diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c > > > index 363695b33..dca408a5c 100644 > > > --- a/tools/virtio/virtio_test.c > > > +++ b/tools/virtio/virtio_test.c > > > @@ -25,7 +25,7 @@ > > > #define RINGSIZE 256 > > > #define TEST_BUF_NUM 0x100000 > > > #define BUF_SIZE 1024 > > > -/* Unused */ > > > +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) > > > void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; > > > struct vq_info { > > > @@ -47,6 +47,8 @@ struct vdev_info { > > > int nvqs; > > > void *buf; > > > size_t buf_size; > > > + void *indirects; > > > + size_t indirects_size; > > What are these exactly? > The buffer is used to put indirect descriptors, and the buffer will be added > in the vhost iotlb through VHOST_SET_MEM_TABLE, so that vhost can translate > the descriptors in user mode correctly. Pls come up with a better name. indirect_buf and indirect_buf_size? And add a comment. > > > > > struct vhost_memory *mem; > > > }; > > > @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) > > > static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > { > > > int r; > > > + int nregions = 2; > > > + > > > memset(dev, 0, sizeof *dev); > > > dev->vdev.features = features; > > > INIT_LIST_HEAD(&dev->vdev.vqs); > > > @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) > > > dev->buf_size = BUF_SIZE; > > > dev->buf = malloc(dev->buf_size); > > > assert(dev->buf); > > > - dev->control = open("/dev/vhost-test", O_RDWR); > > > + dev->indirects_size = INDIRECTS_SIZE; > > > + dev->indirects = malloc(dev->indirects_size); > > > + assert(dev->indirects); > > > + dev->control = open("/dev/vhost-test", O_RDWR); > > > assert(dev->control >= 0); > > > r = ioctl(dev->control, VHOST_SET_OWNER, NULL); > > > assert(r >= 0); > > > dev->mem = malloc(offsetof(struct vhost_memory, regions) + > > > - sizeof dev->mem->regions[0]); > > > + (sizeof(dev->mem->regions[0])) * nregions); > > > assert(dev->mem); > > > memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + > > > - sizeof dev->mem->regions[0]); > > > - dev->mem->nregions = 1; > > > + (sizeof(dev->mem->regions[0])) * nregions); > > > + dev->mem->nregions = nregions; > > > dev->mem->regions[0].guest_phys_addr = (long)dev->buf; > > > dev->mem->regions[0].userspace_addr = (long)dev->buf; > > > dev->mem->regions[0].memory_size = dev->buf_size; > > > + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; > > > + dev->mem->regions[1].userspace_addr = (long)dev->indirects; > > > + dev->mem->regions[1].memory_size = dev->indirects_size; > > > r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); > > > assert(r >= 0); > > > } > > > @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) > > > } > > > } > > > +static int test_virtqueue_add_outbuf(struct virtqueue *vq, > > > + struct scatterlist *sg, unsigned int num, > > > + void *data, void *indirects) > > > +{ > > > + int r; > > > + > > > + __kmalloc_fake = indirects; > > > + r = virtqueue_add_outbuf(vq, sg, num, data, > > > + GFP_ATOMIC); > > > + __kmalloc_fake = NULL; > > > + return r; > > > +} > > > + > > Quite a hack. Please add comments with documentation. Also - no way to > > avoid hacks? > > The __kmalloc_fake is refered from vringh_test. > > If not using __kmalloc_fake here, the vhost doesn't know how to translate > the indirects descriptors(user address). > > We may could register a single region as large as the whole virtual space in > the vhost iotlb using 1:1 mapping. > > But since they are tests, IMHO, better here to use VHOST_SET_MEM_TABLE with > more regions. But why do we need to do this on each buffer add? > > > > > static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > bool delayed, int batch, int reset_n, int bufs) > > > { > > > @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > unsigned len; > > > long long spurious = 0; > > > const bool random_batch = batch == RANDOM_BATCH; > > > + void *indirects; > > > r = ioctl(dev->control, VHOST_TEST_RUN, &test); > > > assert(r >= 0); > > > @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > next_reset = INT_MAX; > > > } > > > + /* Don't kfree indirects. */ > > > + __kfree_ignore_start = dev->indirects; > > > + __kfree_ignore_end = dev->indirects + dev->indirects_size; > > > + > > > for (;;) { > > > virtqueue_disable_cb(vq->vq); > > > completed_before = completed; > > > started_before = started; > > > + indirects = dev->indirects; > > > do { > > > const bool reset = completed > next_reset; > > > if (random_batch) > > > @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > sg_init_table(sg, sg_size); > > > for (int i = 0; i < sg_size; ++i) > > > sg_set_buf(&sg[i], dev->buf + i, 0x1); > > > - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, > > > - dev->buf + started, > > > - GFP_ATOMIC); > > > + > > > + // use indirects buffer repeatedly > > > > C style comments please. > It will be modified. > > > > > + if (indirects + sg_size * sizeof(struct vring_desc) > > > > + dev->indirects + dev->indirects_size) > > > + indirects = dev->indirects; > > > + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, > > > + dev->buf + started, indirects); > > > if (unlikely(r != 0)) { > > > if (r == -ENOSPC && > > > started > started_before) > > > @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, > > > } > > > ++started; > > > + indirects += sg_size * sizeof(struct vring_desc); > > > } > > > if (unlikely(!virtqueue_kick(vq->vq))) { > > > r = -1; > > > -- > > > 2.17.1 > _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 4/4] virtio_test: enable indirection feature 2022-07-07 5:59 ` Michael S. Tsirkin (?) @ 2022-07-07 6:05 ` Guo Zhi -1 siblings, 0 replies; 21+ messages in thread From: Guo Zhi @ 2022-07-07 6:05 UTC (permalink / raw) To: Michael S. Tsirkin Cc: jasowang, eperezma, virtualization, linux-kernel, sgarzare On 2022/7/7 13:59, Michael S. Tsirkin wrote: > On Thu, Jul 07, 2022 at 01:56:37PM +0800, Guo Zhi wrote: >> On 2022/7/7 12:59, Michael S. Tsirkin wrote: >>> On Thu, Jul 07, 2022 at 10:44:09AM +0800, Guo Zhi wrote: >>>> Prior implementation don't use indirection feature because there is only >>>> one descriptor for every io event, actually prior implementation don't >>>> support indirection because vhost can't translate and find the indirect >>>> descriptors. This commit enable virtio_test malloc indirect descriptors >>>> in a indirect buffer and map this buffer to vhost, thus resolve this >>>> problem. >>>> >>>> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn> >>>> --- >>>> tools/virtio/virtio_test.c | 50 ++++++++++++++++++++++++++++++++------ >>>> 1 file changed, 42 insertions(+), 8 deletions(-) >>>> >>>> diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c >>>> index 363695b33..dca408a5c 100644 >>>> --- a/tools/virtio/virtio_test.c >>>> +++ b/tools/virtio/virtio_test.c >>>> @@ -25,7 +25,7 @@ >>>> #define RINGSIZE 256 >>>> #define TEST_BUF_NUM 0x100000 >>>> #define BUF_SIZE 1024 >>>> -/* Unused */ >>>> +#define INDIRECTS_SIZE (RINGSIZE * sizeof(struct vring_desc) * 8) >>>> void *__kmalloc_fake, *__kfree_ignore_start, *__kfree_ignore_end; >>>> struct vq_info { >>>> @@ -47,6 +47,8 @@ struct vdev_info { >>>> int nvqs; >>>> void *buf; >>>> size_t buf_size; >>>> + void *indirects; >>>> + size_t indirects_size; >>> What are these exactly? >> The buffer is used to put indirect descriptors, and the buffer will be added >> in the vhost iotlb through VHOST_SET_MEM_TABLE, so that vhost can translate >> the descriptors in user mode correctly. > Pls come up with a better name. indirect_buf and indirect_buf_size? > And add a comment. Will be modified in next version batch. > >>>> struct vhost_memory *mem; >>>> }; >>>> @@ -131,6 +133,8 @@ static void vq_info_add(struct vdev_info *dev, int num) >>>> static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >>>> { >>>> int r; >>>> + int nregions = 2; >>>> + >>>> memset(dev, 0, sizeof *dev); >>>> dev->vdev.features = features; >>>> INIT_LIST_HEAD(&dev->vdev.vqs); >>>> @@ -138,19 +142,25 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features) >>>> dev->buf_size = BUF_SIZE; >>>> dev->buf = malloc(dev->buf_size); >>>> assert(dev->buf); >>>> - dev->control = open("/dev/vhost-test", O_RDWR); >>>> + dev->indirects_size = INDIRECTS_SIZE; >>>> + dev->indirects = malloc(dev->indirects_size); >>>> + assert(dev->indirects); >>>> + dev->control = open("/dev/vhost-test", O_RDWR); >>>> assert(dev->control >= 0); >>>> r = ioctl(dev->control, VHOST_SET_OWNER, NULL); >>>> assert(r >= 0); >>>> dev->mem = malloc(offsetof(struct vhost_memory, regions) + >>>> - sizeof dev->mem->regions[0]); >>>> + (sizeof(dev->mem->regions[0])) * nregions); >>>> assert(dev->mem); >>>> memset(dev->mem, 0, offsetof(struct vhost_memory, regions) + >>>> - sizeof dev->mem->regions[0]); >>>> - dev->mem->nregions = 1; >>>> + (sizeof(dev->mem->regions[0])) * nregions); >>>> + dev->mem->nregions = nregions; >>>> dev->mem->regions[0].guest_phys_addr = (long)dev->buf; >>>> dev->mem->regions[0].userspace_addr = (long)dev->buf; >>>> dev->mem->regions[0].memory_size = dev->buf_size; >>>> + dev->mem->regions[1].guest_phys_addr = (long)dev->indirects; >>>> + dev->mem->regions[1].userspace_addr = (long)dev->indirects; >>>> + dev->mem->regions[1].memory_size = dev->indirects_size; >>>> r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem); >>>> assert(r >= 0); >>>> } >>>> @@ -170,6 +180,19 @@ static void wait_for_interrupt(struct vdev_info *dev) >>>> } >>>> } >>>> +static int test_virtqueue_add_outbuf(struct virtqueue *vq, >>>> + struct scatterlist *sg, unsigned int num, >>>> + void *data, void *indirects) >>>> +{ >>>> + int r; >>>> + >>>> + __kmalloc_fake = indirects; >>>> + r = virtqueue_add_outbuf(vq, sg, num, data, >>>> + GFP_ATOMIC); >>>> + __kmalloc_fake = NULL; >>>> + return r; >>>> +} >>>> + >>> Quite a hack. Please add comments with documentation. Also - no way to >>> avoid hacks? >> The __kmalloc_fake is refered from vringh_test. >> >> If not using __kmalloc_fake here, the vhost doesn't know how to translate >> the indirects descriptors(user address). >> >> We may could register a single region as large as the whole virtual space in >> the vhost iotlb using 1:1 mapping. >> >> But since they are tests, IMHO, better here to use VHOST_SET_MEM_TABLE with >> more regions. > But why do we need to do this on each buffer add? Because kmalloc in virtio_test will return address __kmalloc_fake. Since there are many descriptors batched here, It will be erase existed unused descriptors' indirect descriptors if using the same area for every buffer add. > >>>> static void run_test(struct vdev_info *dev, struct vq_info *vq, >>>> bool delayed, int batch, int reset_n, int bufs) >>>> { >>>> @@ -181,6 +204,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >>>> unsigned len; >>>> long long spurious = 0; >>>> const bool random_batch = batch == RANDOM_BATCH; >>>> + void *indirects; >>>> r = ioctl(dev->control, VHOST_TEST_RUN, &test); >>>> assert(r >= 0); >>>> @@ -188,10 +212,15 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >>>> next_reset = INT_MAX; >>>> } >>>> + /* Don't kfree indirects. */ >>>> + __kfree_ignore_start = dev->indirects; >>>> + __kfree_ignore_end = dev->indirects + dev->indirects_size; >>>> + >>>> for (;;) { >>>> virtqueue_disable_cb(vq->vq); >>>> completed_before = completed; >>>> started_before = started; >>>> + indirects = dev->indirects; >>>> do { >>>> const bool reset = completed > next_reset; >>>> if (random_batch) >>>> @@ -203,9 +232,13 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >>>> sg_init_table(sg, sg_size); >>>> for (int i = 0; i < sg_size; ++i) >>>> sg_set_buf(&sg[i], dev->buf + i, 0x1); >>>> - r = virtqueue_add_outbuf(vq->vq, sg, sg_size, >>>> - dev->buf + started, >>>> - GFP_ATOMIC); >>>> + >>>> + // use indirects buffer repeatedly >>> C style comments please. >> It will be modified. >>>> + if (indirects + sg_size * sizeof(struct vring_desc) > >>>> + dev->indirects + dev->indirects_size) >>>> + indirects = dev->indirects; >>>> + r = test_virtqueue_add_outbuf(vq->vq, sg, sg_size, >>>> + dev->buf + started, indirects); >>>> if (unlikely(r != 0)) { >>>> if (r == -ENOSPC && >>>> started > started_before) >>>> @@ -216,6 +249,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, >>>> } >>>> ++started; >>>> + indirects += sg_size * sizeof(struct vring_desc); >>>> } >>>> if (unlikely(!virtqueue_kick(vq->vq))) { >>>> r = -1; >>>> -- >>>> 2.17.1 ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2022-07-07 12:19 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-07-07 2:44 [PATCH v2 0/4] virtio/virtio_test Guo Zhi 2022-07-07 2:44 ` [PATCH v2 1/4] virtio_test: kick vhost for a batch of descriptors Guo Zhi 2022-07-07 2:44 ` [PATCH v2 2/4] virtio_test: move magic number in code as defined constant Guo Zhi 2022-07-07 5:09 ` Michael S. Tsirkin 2022-07-07 5:09 ` Michael S. Tsirkin 2022-07-07 6:17 ` Guo Zhi 2022-07-07 7:36 ` Michael S. Tsirkin 2022-07-07 7:36 ` Michael S. Tsirkin 2022-07-07 12:15 ` Guo Zhi 2022-07-07 12:19 ` Guo Zhi 2022-07-07 2:44 ` [PATCH v2 3/4] virtio_test: use random length scatterlists to test descriptor chain Guo Zhi 2022-07-07 5:16 ` Michael S. Tsirkin 2022-07-07 5:16 ` Michael S. Tsirkin 2022-07-07 6:24 ` Guo Zhi 2022-07-07 2:44 ` [PATCH v2 4/4] virtio_test: enable indirection feature Guo Zhi 2022-07-07 4:59 ` Michael S. Tsirkin 2022-07-07 4:59 ` Michael S. Tsirkin 2022-07-07 5:56 ` Guo Zhi 2022-07-07 5:59 ` Michael S. Tsirkin 2022-07-07 5:59 ` Michael S. Tsirkin 2022-07-07 6:05 ` Guo Zhi
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.