From: Yunsheng Lin <hidden> Date: 2021-07-01 12:27:25
Currently ptr_ring selftest is embedded within the virtio
selftest, which involves some specific virtio operation,
such as notifying and kicking.
As ptr_ring has been used by various subsystems, it deserves
it's owner selftest in order to benchmark different usecase
of ptr_ring, such as page pool and pfifo_fast qdisc.
So add a simple application to benchmark ptr_ring performance.
Currently two test mode is supported:
Mode 0: Both producing and consuming is done in a single thread,
it is called simple test mode in the test app.
Mode 1: Producing and consuming is done in different thread
concurrently, also known as SPSC(single-producer/
single-consumer) test.
The multi-producer/single-consumer test for pfifo_fast case is
not added yet, which can be added if using CAS atomic operation
to enable lockless multi-producer is proved to be better than
using r->producer_lock.
Signed-off-by: Yunsheng Lin <redacted>
---
V3: Remove timestamp sampling, use standard C library as much
as possible.
---
MAINTAINERS | 5 +
tools/testing/selftests/ptr_ring/Makefile | 6 +
tools/testing/selftests/ptr_ring/ptr_ring_test.c | 224 +++++++++++++++++++++++
tools/testing/selftests/ptr_ring/ptr_ring_test.h | 130 +++++++++++++
4 files changed, 365 insertions(+)
create mode 100644 tools/testing/selftests/ptr_ring/Makefile
create mode 100644 tools/testing/selftests/ptr_ring/ptr_ring_test.c
create mode 100644 tools/testing/selftests/ptr_ring/ptr_ring_test.h
@@ -0,0 +1,224 @@+// SPDX-License-Identifier: GPL-2.0-or-later+/*+*Copyright(C)2021HiSiliconLimited.+*/++#include<stdio.h>+#include<stdlib.h>+#include<unistd.h>+#include<string.h>+#include<errno.h>+#include<malloc.h>+#include<stdbool.h>++#include"ptr_ring_test.h"+#include"../../../../include/linux/ptr_ring.h"++#define MIN_RING_SIZE 2+#define MAX_RING_SIZE 10000000++staticstructptr_ringring____cacheline_aligned_in_smp;++structworker_info{+pthread_ttid;+inttest_count;+boolerror;+};++staticvoid*produce_worker(void*arg)+{+structworker_info*info=arg;+unsignedlongi=0;+intret;++while(++i<=info->test_count){+while(__ptr_ring_full(&ring))+cpu_relax();++ret=__ptr_ring_produce(&ring,(void*)i);+if(ret){+fprintf(stderr,"produce failed: %d\n",ret);+info->error=true;+returnNULL;+}+}++info->error=false;++returnNULL;+}++staticvoid*consume_worker(void*arg)+{+structworker_info*info=arg;+unsignedlongi=0;+int*ptr;++while(++i<=info->test_count){+while(__ptr_ring_empty(&ring))+cpu_relax();++ptr=__ptr_ring_consume(&ring);+if((unsignedlong)ptr!=i){+fprintf(stderr,"consumer failed, ptr: %lu, i: %lu\n",+(unsignedlong)ptr,i);+info->error=true;+returnNULL;+}+}++if(!__ptr_ring_empty(&ring)){+fprintf(stderr,"ring should be empty, test failed\n");+info->error=true;+returnNULL;+}++info->error=false;+returnNULL;+}++/* test case for single producer single consumer */+staticvoidspsc_test(intsize,intcount)+{+structworker_infoproducer,consumer;+pthread_attr_tattr;+void*res;+intret;++ret=ptr_ring_init(&ring,size,0);+if(ret){+fprintf(stderr,"init failed: %d\n",ret);+return;+}++producer.test_count=count;+consumer.test_count=count;++ret=pthread_attr_init(&attr);+if(ret){+fprintf(stderr,"pthread attr init failed: %d\n",ret);+gotoout;+}++ret=pthread_create(&producer.tid,&attr,+produce_worker,&producer);+if(ret){+fprintf(stderr,"create producer thread failed: %d\n",ret);+gotoout;+}++ret=pthread_create(&consumer.tid,&attr,+consume_worker,&consumer);+if(ret){+fprintf(stderr,"create consumer thread failed: %d\n",ret);+gotoout;+}++ret=pthread_join(producer.tid,&res);+if(ret){+fprintf(stderr,"join producer thread failed: %d\n",ret);+gotoout;+}++ret=pthread_join(consumer.tid,&res);+if(ret){+fprintf(stderr,"join consumer thread failed: %d\n",ret);+gotoout;+}++if(producer.error||consumer.error){+fprintf(stderr,"spsc test failed\n");+gotoout;+}++printf("ptr_ring(size:%d) perf spsc test produced/comsumed %d items, finished\n",+size,count);+out:+ptr_ring_cleanup(&ring,NULL);+}++staticvoidsimple_test(intsize,intcount)+{+structtimevalstart,end;+inti=0;+int*ptr;+intret;++ret=ptr_ring_init(&ring,size,0);+if(ret){+fprintf(stderr,"init failed: %d\n",ret);+return;+}++while(++i<=count){+ret=__ptr_ring_produce(&ring,&count);+if(ret){+fprintf(stderr,"produce failed: %d\n",ret);+gotoout;+}++ptr=__ptr_ring_consume(&ring);+if(ptr!=&count){+fprintf(stderr,"consume failed: %p\n",ptr);+gotoout;+}+}++printf("ptr_ring(size:%d) perf simple test produced/consumed %d items, finished\n",+size,count);++out:+ptr_ring_cleanup(&ring,NULL);+}++intmain(intargc,char*argv[])+{+intcount=1000000;+intsize=1000;+intmode=0;+intopt;++while((opt=getopt(argc,argv,"N:s:m:h"))!=-1){+switch(opt){+case'N':+count=atoi(optarg);+break;+case's':+size=atoi(optarg);+break;+case'm':+mode=atoi(optarg);+break;+case'h':+printf("usage: ptr_ring_test [-N COUNT] [-s RING_SIZE] [-m TEST_MODE]\n");+return0;+default:+return-1;+}+}++if(count<=0){+fprintf(stderr,"invalid test count, must be > 0\n");+return-1;+}++if(size<MIN_RING_SIZE||size>MAX_RING_SIZE){+fprintf(stderr,"invalid ring size, must be in %d-%d\n",+MIN_RING_SIZE,MAX_RING_SIZE);+return-1;+}++switch(mode){+case0:+simple_test(size,count);+break;+case1:+spsc_test(size,count);+break;+default:+fprintf(stderr,"invalid test mode\n");+return-1;+}++return0;+}
From: Yunsheng Lin <hidden> Date: 2021-07-01 12:27:28
Currently r->queue[] clearing is done before r->consumer_head
updating, which makes the __ptr_ring_empty() returning false
positive result(the ring is non-empty, but __ptr_ring_empty()
suggest that it is empty) if the checking is done after the
r->queue clearing and before the consumer_head moving forward.
Move the r->queue[] clearing after consumer_head moving forward
to avoid the above case.
As a side effect of above change, a consumer_head checking is
avoided for the likely case, and it has noticeable performance
improvement when it is tested using the ptr_ring_test selftest
added in the previous patch.
Tested using the "perf stat -r 1000 ./ptr_ring_test -s 1000 -m 1
-N 100000000", comparing the elapsed time:
arch unpatched patched improvement
arm64 2.087205 sec 1.888224 sec +9.5%
X86 2.6538 sec 2.5422 sec +4.2%
Signed-off-by: Yunsheng Lin <redacted>
---
V3: adjust the title and comment log according to disscusion in
V2, and update performance data using "perf stat -r".
V2: Add performance data.
---
include/linux/ptr_ring.h | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
@@ -261,8 +261,7 @@ static inline void __ptr_ring_discard_one(struct ptr_ring *r)/* Note: we must keep consumer_head valid at all times for __ptr_ring_empty*toworkcorrectly.*/-intconsumer_head=r->consumer_head;-inthead=consumer_head++;+intconsumer_head=r->consumer_head+1;/* Once we have processed enough entries invalidate them in*theringallatoncesoproducercanreusetheirspaceinthering.
@@ -271,19 +270,27 @@ static inline void __ptr_ring_discard_one(struct ptr_ring *r)*/if(unlikely(consumer_head-r->consumer_tail>=r->batch||consumer_head>=r->size)){+inttail=r->consumer_tail;++if(unlikely(consumer_head>=r->size)){+r->consumer_tail=0;+WRITE_ONCE(r->consumer_head,0);+}else{+r->consumer_tail=consumer_head;+WRITE_ONCE(r->consumer_head,consumer_head);+}+/* Zero out entries in the reverse order: this way we touch the*cachelinethatproducermightcurrentlybereadingthelast;*producerwon'tmakeprogressandtouchothercachelines*besidesthefirstoneuntilwewriteoutallentries.*/-while(likely(head>=r->consumer_tail))-r->queue[head--]=NULL;-r->consumer_tail=consumer_head;-}-if(unlikely(consumer_head>=r->size)){-consumer_head=0;-r->consumer_tail=0;+while(likely(--consumer_head>=tail))+r->queue[consumer_head]=NULL;++return;}+/* matching READ_ONCE in __ptr_ring_empty for lockless tests */WRITE_ONCE(r->consumer_head,consumer_head);}
From: Yunsheng Lin <hidden> Date: 2021-07-01 12:27:30
After r->consumer_head is updated in __ptr_ring_discard_one(),
r->queue[r->consumer_head] is already cleared in the previous
round of __ptr_ring_discard_one(). But there is no guarantee
other thread will see the r->queue[r->consumer_head] being
NULL because there is no explicit barrier between r->queue[]
clearing and r->consumer_head updating.
So add two explicit barrier to make sure r->queue[] cleared in
__ptr_ring_discard_one() to be visible to other cpu, mainly to
make sure the cpu calling the __ptr_ring_empty() will see the
correct r->queue[r->consumer_head].
Hopefully the previous and this patch have ensured the correct
visibility of r->queue[], so update the comment accordingly
about __ptr_ring_empty().
Tested using the "perf stat -r 1000 ./ptr_ring_test -s 1000 -m 1
-N 100000000", comparing the elapsed time:
arch unpatched patched improvement
arm64 1.888224 sec 1.893673 sec -0.2%
X86 2.5422 sec 2.5587 sec -0.6%
Reported-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Yunsheng Lin <redacted>
---
include/linux/ptr_ring.h | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
From: Jason Wang <hidden> Date: 2021-07-02 06:43:22
在 2021/7/1 下午8:26, Yunsheng Lin 写道:
quoted hunk
Currently ptr_ring selftest is embedded within the virtio
selftest, which involves some specific virtio operation,
such as notifying and kicking.
As ptr_ring has been used by various subsystems, it deserves
it's owner selftest in order to benchmark different usecase
of ptr_ring, such as page pool and pfifo_fast qdisc.
So add a simple application to benchmark ptr_ring performance.
Currently two test mode is supported:
Mode 0: Both producing and consuming is done in a single thread,
it is called simple test mode in the test app.
Mode 1: Producing and consuming is done in different thread
concurrently, also known as SPSC(single-producer/
single-consumer) test.
The multi-producer/single-consumer test for pfifo_fast case is
not added yet, which can be added if using CAS atomic operation
to enable lockless multi-producer is proved to be better than
using r->producer_lock.
Signed-off-by: Yunsheng Lin <redacted>
---
V3: Remove timestamp sampling, use standard C library as much
as possible.
---
MAINTAINERS | 5 +
tools/testing/selftests/ptr_ring/Makefile | 6 +
tools/testing/selftests/ptr_ring/ptr_ring_test.c | 224 +++++++++++++++++++++++
tools/testing/selftests/ptr_ring/ptr_ring_test.h | 130 +++++++++++++
4 files changed, 365 insertions(+)
create mode 100644 tools/testing/selftests/ptr_ring/Makefile
create mode 100644 tools/testing/selftests/ptr_ring/ptr_ring_test.c
create mode 100644 tools/testing/selftests/ptr_ring/ptr_ring_test.h
From: Jason Wang <hidden> Date: 2021-07-02 06:46:08
在 2021/7/1 下午8:26, Yunsheng Lin 写道:
Currently r->queue[] clearing is done before r->consumer_head
updating, which makes the __ptr_ring_empty() returning false
positive result(the ring is non-empty, but __ptr_ring_empty()
suggest that it is empty) if the checking is done after the
r->queue clearing and before the consumer_head moving forward.
Move the r->queue[] clearing after consumer_head moving forward
to avoid the above case.
As a side effect of above change, a consumer_head checking is
avoided for the likely case, and it has noticeable performance
improvement when it is tested using the ptr_ring_test selftest
added in the previous patch.
Tested using the "perf stat -r 1000 ./ptr_ring_test -s 1000 -m 1
-N 100000000", comparing the elapsed time:
arch unpatched patched improvement
arm64 2.087205 sec 1.888224 sec +9.5%
X86 2.6538 sec 2.5422 sec +4.2%
I think we need the number of real workloads here.
Thanks
quoted hunk
Signed-off-by: Yunsheng Lin <redacted>
---
V3: adjust the title and comment log according to disscusion in
V2, and update performance data using "perf stat -r".
V2: Add performance data.
---
include/linux/ptr_ring.h | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
@@ -261,8 +261,7 @@ static inline void __ptr_ring_discard_one(struct ptr_ring *r)/* Note: we must keep consumer_head valid at all times for __ptr_ring_empty*toworkcorrectly.*/-intconsumer_head=r->consumer_head;-inthead=consumer_head++;+intconsumer_head=r->consumer_head+1;/* Once we have processed enough entries invalidate them in*theringallatoncesoproducercanreusetheirspaceinthering.
@@ -271,19 +270,27 @@ static inline void __ptr_ring_discard_one(struct ptr_ring *r)*/if(unlikely(consumer_head-r->consumer_tail>=r->batch||consumer_head>=r->size)){+inttail=r->consumer_tail;++if(unlikely(consumer_head>=r->size)){+r->consumer_tail=0;+WRITE_ONCE(r->consumer_head,0);+}else{+r->consumer_tail=consumer_head;+WRITE_ONCE(r->consumer_head,consumer_head);+}+/* Zero out entries in the reverse order: this way we touch the*cachelinethatproducermightcurrentlybereadingthelast;*producerwon'tmakeprogressandtouchothercachelines*besidesthefirstoneuntilwewriteoutallentries.*/-while(likely(head>=r->consumer_tail))-r->queue[head--]=NULL;-r->consumer_tail=consumer_head;-}-if(unlikely(consumer_head>=r->size)){-consumer_head=0;-r->consumer_tail=0;+while(likely(--consumer_head>=tail))+r->queue[consumer_head]=NULL;++return;}+/* matching READ_ONCE in __ptr_ring_empty for lockless tests */WRITE_ONCE(r->consumer_head,consumer_head);}
From: Yunsheng Lin <hidden> Date: 2021-07-02 08:17:25
On 2021/7/2 14:43, Jason Wang wrote:
在 2021/7/1 下午8:26, Yunsheng Lin 写道:
quoted
Currently ptr_ring selftest is embedded within the virtio
selftest, which involves some specific virtio operation,
such as notifying and kicking.
As ptr_ring has been used by various subsystems, it deserves
it's owner selftest in order to benchmark different usecase
of ptr_ring, such as page pool and pfifo_fast qdisc.
So add a simple application to benchmark ptr_ring performance.
Currently two test mode is supported:
Mode 0: Both producing and consuming is done in a single thread,
it is called simple test mode in the test app.
Mode 1: Producing and consuming is done in different thread
concurrently, also known as SPSC(single-producer/
single-consumer) test.
The multi-producer/single-consumer test for pfifo_fast case is
not added yet, which can be added if using CAS atomic operation
to enable lockless multi-producer is proved to be better than
using r->producer_lock.
Signed-off-by: Yunsheng Lin <redacted>
---
V3: Remove timestamp sampling, use standard C library as much
as possible.
[...]
quoted
+static void *produce_worker(void *arg)
+{
+ struct worker_info *info = arg;
+ unsigned long i = 0;
+ int ret;
+
+ while (++i <= info->test_count) {
+ while (__ptr_ring_full(&ring))
+ cpu_relax();
+
+ ret = __ptr_ring_produce(&ring, (void *)i);
+ if (ret) {
+ fprintf(stderr, "produce failed: %d\n", ret);
+ info->error = true;
+ return NULL;
+ }
+ }
+
+ info->error = false;
+
+ return NULL;
+}
+
+static void *consume_worker(void *arg)
+{
+ struct worker_info *info = arg;
+ unsigned long i = 0;
+ int *ptr;
+
+ while (++i <= info->test_count) {
+ while (__ptr_ring_empty(&ring))
+ cpu_relax();
Any reason for not simply use __ptr_ring_consume() here?
No particular reason, just to make sure the ring is
non-empty before doing the enqueuing, we could check
if the __ptr_ring_consume() return NULL to decide
the if the ring is empty. Using __ptr_ring_consume()
here enable testing the correctness and performance of
__ptr_ring_consume() too.
Let's reuse ptr_ring.c in tools/virtio/ringtest. Nothing virt specific there.
It *does* have some virtio specific at the end of ptr_ring.c.
It can be argued that the ptr_ring.c in tools/virtio/ringtest
could be refactored to remove the function related to virtio.
But as mentioned in the previous disscusion [1], the tools/virtio/
seems to have compile error in the latest kernel, it does not seems
right to reuse that. And most of testcase in tools/virtio/ seems
better be in tools/virtio/ringtest instead,so until the testcase
in tools/virtio/ is compile-error-free and moved to tools/testing/
selftests/, it seems better not to reuse it for now.
1. https://patchwork.kernel.org/project/netdevbpf/patch/1624591136-6647-2-git-send-email-linyunsheng@huawei.com/#24278945
From: "Michael S. Tsirkin" <mst@redhat.com> Date: 2021-07-02 08:30:59
On Fri, Jul 02, 2021 at 04:17:17PM +0800, Yunsheng Lin wrote:
quoted
Let's reuse ptr_ring.c in tools/virtio/ringtest. Nothing virt specific there.
It *does* have some virtio specific at the end of ptr_ring.c.
It can be argued that the ptr_ring.c in tools/virtio/ringtest
could be refactored to remove the function related to virtio.
But as mentioned in the previous disscusion [1], the tools/virtio/
seems to have compile error in the latest kernel, it does not seems
right to reuse that.
And most of testcase in tools/virtio/ seems
better be in tools/virtio/ringtest instead,so until the testcase
in tools/virtio/ is compile-error-free and moved to tools/testing/
selftests/, it seems better not to reuse it for now.
That's a great reason to reuse - so tools/virtio/ stays working.
Please just fix that.
--
MST
From: Yunsheng Lin <hidden> Date: 2021-07-02 08:40:58
On 2021/7/2 14:45, Jason Wang wrote:
在 2021/7/1 下午8:26, Yunsheng Lin 写道:
quoted
Currently r->queue[] clearing is done before r->consumer_head
updating, which makes the __ptr_ring_empty() returning false
positive result(the ring is non-empty, but __ptr_ring_empty()
suggest that it is empty) if the checking is done after the
r->queue clearing and before the consumer_head moving forward.
Move the r->queue[] clearing after consumer_head moving forward
to avoid the above case.
As a side effect of above change, a consumer_head checking is
avoided for the likely case, and it has noticeable performance
improvement when it is tested using the ptr_ring_test selftest
added in the previous patch.
Tested using the "perf stat -r 1000 ./ptr_ring_test -s 1000 -m 1
-N 100000000", comparing the elapsed time:
arch unpatched patched improvement
arm64 2.087205 sec 1.888224 sec +9.5%
X86 2.6538 sec 2.5422 sec +4.2%
I think we need the number of real workloads here.
As it is a low optimization, and overhead of enqueuing
and dequeuing is small for any real workloads, so the
performance improvement could be buried in deviation.
And that is why the ptr_ring_test is added, the about
10% improvement for arm64 seems big, but note that it
is tested using the taskset to avoid the numa effects
for arm64.
Anyway, here is the performance data for pktgen in
queue_xmit mode + dummy netdev with pfifo_fast(which
uses ptr_ring too), which is not obvious to the above
data:
threads unpatched unpatched delta
1 3.21Mpps 3.23Mpps +0.6%
2 5.56Mpps 3.59Mpps +0.5%
4 5.58Mpps 5.61Mpps +0.5%
8 2.76Mpps 2.75Mpps -0.3%
16 2.23Mpps 2.22Mpps -0.4%
From: Yunsheng Lin <hidden> Date: 2021-07-02 08:46:26
On 2021/7/2 16:30, Michael S. Tsirkin wrote:
On Fri, Jul 02, 2021 at 04:17:17PM +0800, Yunsheng Lin wrote:
quoted
quoted
Let's reuse ptr_ring.c in tools/virtio/ringtest. Nothing virt specific there.
It *does* have some virtio specific at the end of ptr_ring.c.
It can be argued that the ptr_ring.c in tools/virtio/ringtest
could be refactored to remove the function related to virtio.
But as mentioned in the previous disscusion [1], the tools/virtio/
seems to have compile error in the latest kernel, it does not seems
right to reuse that.
And most of testcase in tools/virtio/ seems
better be in tools/virtio/ringtest instead,so until the testcase
in tools/virtio/ is compile-error-free and moved to tools/testing/
selftests/, it seems better not to reuse it for now.
That's a great reason to reuse - so tools/virtio/ stays working.
Please just fix that.
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
From: Jason Wang <hidden> Date: 2021-07-02 09:05:00
在 2021/7/2 下午4:46, Yunsheng Lin 写道:
On 2021/7/2 16:30, Michael S. Tsirkin wrote:
quoted
On Fri, Jul 02, 2021 at 04:17:17PM +0800, Yunsheng Lin wrote:
quoted
quoted
Let's reuse ptr_ring.c in tools/virtio/ringtest. Nothing virt specific there.
It *does* have some virtio specific at the end of ptr_ring.c.
They are just wrappers to make ptr ring works like a virtio ring. We can
split them out into another file if necessary.
quoted
quoted
It can be argued that the ptr_ring.c in tools/virtio/ringtest
could be refactored to remove the function related to virtio.
But as mentioned in the previous disscusion [1], the tools/virtio/
seems to have compile error in the latest kernel, it does not seems
right to reuse that.
And most of testcase in tools/virtio/ seems
better be in tools/virtio/ringtest instead,so until the testcase
in tools/virtio/ is compile-error-free and moved to tools/testing/
selftests/, it seems better not to reuse it for now.
That's a great reason to reuse - so tools/virtio/ stays working.
Please just fix that.
+1
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
So ringtest is used for bench-marking the ring performance for different
format. Virtio is only one of the supported ring format, ptr ring is
another. Wrappers were used to reuse the same test logic.
Though you may see host/guest in the test, it's in fact done via two
processes.
We need figure out:
1) why the current ringtest.c does not fit for your requirement (it has
SPSC test)
2) why can't we tweak the ptr_ring.c to be used by both ring_test and
your benchmark
If neither of the above work, we can invent new ptr_ring infrastructure
under tests/
Thanks
From: Yunsheng Lin <hidden> Date: 2021-07-02 09:54:50
On 2021/7/2 17:04, Jason Wang wrote:
[...]
quoted
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
So ringtest is used for bench-marking the ring performance for different format. Virtio is only one of the supported ring format, ptr ring is another. Wrappers were used to reuse the same test logic.
Though you may see host/guest in the test, it's in fact done via two processes.
We need figure out:
1) why the current ringtest.c does not fit for your requirement (it has SPSC test)
There is MPSC case used by pfifo_fast, it make more sense to use a separate selftest
for ptr_ring as ptr_ring has been used by various subsystems.
2) why can't we tweak the ptr_ring.c to be used by both ring_test and your benchmark
Actually that is what I do in this patch, move the specific part related to ptr_ring
to ptr_ring_test.h. When the virtio testing is refactored to work, it can reuse the
abstract layer in ptr_ring_test.h too.
If neither of the above work, we can invent new ptr_ring infrastructure under tests/
Thanks
From: "Michael S. Tsirkin" <mst@redhat.com> Date: 2021-07-02 14:17:09
On Fri, Jul 02, 2021 at 05:04:44PM +0800, Jason Wang wrote:
在 2021/7/2 下午4:46, Yunsheng Lin 写道:
quoted
On 2021/7/2 16:30, Michael S. Tsirkin wrote:
quoted
On Fri, Jul 02, 2021 at 04:17:17PM +0800, Yunsheng Lin wrote:
quoted
quoted
Let's reuse ptr_ring.c in tools/virtio/ringtest. Nothing virt specific there.
It *does* have some virtio specific at the end of ptr_ring.c.
They are just wrappers to make ptr ring works like a virtio ring. We can
split them out into another file if necessary.
quoted
quoted
quoted
It can be argued that the ptr_ring.c in tools/virtio/ringtest
could be refactored to remove the function related to virtio.
But as mentioned in the previous disscusion [1], the tools/virtio/
seems to have compile error in the latest kernel, it does not seems
right to reuse that.
And most of testcase in tools/virtio/ seems
better be in tools/virtio/ringtest instead,so until the testcase
in tools/virtio/ is compile-error-free and moved to tools/testing/
selftests/, it seems better not to reuse it for now.
That's a great reason to reuse - so tools/virtio/ stays working.
Please just fix that.
+1
quoted
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
So ringtest is used for bench-marking the ring performance for different
format. Virtio is only one of the supported ring format, ptr ring is
another. Wrappers were used to reuse the same test logic.
Though you may see host/guest in the test, it's in fact done via two
processes.
We need figure out:
1) why the current ringtest.c does not fit for your requirement (it has SPSC
test)
2) why can't we tweak the ptr_ring.c to be used by both ring_test and your
benchmark
If neither of the above work, we can invent new ptr_ring infrastructure
under tests/
Thanks
For me 1) is not a question.
All the available/used terminology is not an ideal fit for ptr ring.
With virtio buffers are always owned by driver (producer) so producer
has a way to find out if a buffer has been consumed. With ptr ring
there's no way for producer to know a buffer has been consumed.
The test hacks around that but it is very reasonable
not to want to rely on that.
However 2) is very much a question. We can split ptr_ring
to the preamble and virtio related hacks.
So all the portability infrastructure for building
kernel code from userspace, command line parsing,
run-on-all.sh to figure out affinity effects,
all that can and should IMHO be reused and not copy-pasted.
From: "Michael S. Tsirkin" <mst@redhat.com> Date: 2021-07-02 14:18:59
On Fri, Jul 02, 2021 at 05:54:42PM +0800, Yunsheng Lin wrote:
On 2021/7/2 17:04, Jason Wang wrote:
quoted
[...]
quoted
quoted
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
So ringtest is used for bench-marking the ring performance for different format. Virtio is only one of the supported ring format, ptr ring is another. Wrappers were used to reuse the same test logic.
Though you may see host/guest in the test, it's in fact done via two processes.
We need figure out:
1) why the current ringtest.c does not fit for your requirement (it has SPSC test)
There is MPSC case used by pfifo_fast, it make more sense to use a separate selftest
for ptr_ring as ptr_ring has been used by various subsystems.
quoted
2) why can't we tweak the ptr_ring.c to be used by both ring_test and your benchmark
Actually that is what I do in this patch, move the specific part related to ptr_ring
to ptr_ring_test.h. When the virtio testing is refactored to work, it can reuse the
abstract layer in ptr_ring_test.h too.
Sounds good. But that refactoring will be up to you as a contributor.
quoted
If neither of the above work, we can invent new ptr_ring infrastructure under tests/
Thanks
From: Yunsheng Lin <hidden> Date: 2021-07-05 01:43:53
On 2021/7/2 22:18, Michael S. Tsirkin wrote:
On Fri, Jul 02, 2021 at 05:54:42PM +0800, Yunsheng Lin wrote:
quoted
On 2021/7/2 17:04, Jason Wang wrote:
quoted
[...]
quoted
quoted
I understand that you guys like to see a working testcase of virtio.
I would love to do that if I have the time and knowledge of virtio,
But I do not think I have the time and I am familiar enough with
virtio to fix that now.
So ringtest is used for bench-marking the ring performance for different format. Virtio is only one of the supported ring format, ptr ring is another. Wrappers were used to reuse the same test logic.
Though you may see host/guest in the test, it's in fact done via two processes.
We need figure out:
1) why the current ringtest.c does not fit for your requirement (it has SPSC test)
There is MPSC case used by pfifo_fast, it make more sense to use a separate selftest
for ptr_ring as ptr_ring has been used by various subsystems.
quoted
2) why can't we tweak the ptr_ring.c to be used by both ring_test and your benchmark
Actually that is what I do in this patch, move the specific part related to ptr_ring
to ptr_ring_test.h. When the virtio testing is refactored to work, it can reuse the
abstract layer in ptr_ring_test.h too.
Sounds good. But that refactoring will be up to you as a contributor.
It seems that tools/include/* have a lot of portability infrastructure for building
kernel code from userspace, will try to refactor the ptr_ring.h to use the portability
infrastructure in tools/include/* when building ptr_ring.h from userspace.