On 2021/7/2 14:43, Jason Wang wrote: > > 在 2021/7/1 下午8:26, Yunsheng Lin 写道: >> 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 <linyunsheng@xxxxxxxxxx> >> --- >> V3: Remove timestamp sampling, use standard C library as much >> as possible. [...] >> +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. > > >> + >> + ptr = __ptr_ring_consume(&ring); >> + if ((unsigned long)ptr != i) { >> + fprintf(stderr, "consumer failed, ptr: %lu, i: %lu\n", >> + (unsigned long)ptr, i); >> + info->error = true; >> + return NULL; >> + } >> + } >> + >> + if (!__ptr_ring_empty(&ring)) { >> + fprintf(stderr, "ring should be empty, test failed\n"); >> + info->error = true; >> + return NULL; >> + } >> + >> + info->error = false; >> + return NULL; >> +} >> + [...] >> + >> + return 0; >> +} >> diff --git a/tools/testing/selftests/ptr_ring/ptr_ring_test.h b/tools/testing/selftests/ptr_ring/ptr_ring_test.h >> new file mode 100644 >> index 0000000..32bfefb >> --- /dev/null >> +++ b/tools/testing/selftests/ptr_ring/ptr_ring_test.h > > > 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@xxxxxxxxxx/#24278945 > > Thanks > [...] > > . >