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
[...]
.