
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@huawei.com> --- 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-s...
Thanks
[...]
.