All of lore.kernel.org
 help / color / mirror / Atom feed
* [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

* [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

* [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 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 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 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

* 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 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

* 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

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.