Using kunit to write tests for new work on dmabuf is coming up:
https://lore.kernel.org/all/26-v1-b5cab63049c0+191af-dmabuf_map_type_jgg@nvi...
Replace the custom test framework with kunit to avoid maintaining two concurrent test frameworks.
The conversion minimizes code changes and uses simple pattern-oriented reworks to reduce the chance of breaking any tests. Aside from adding the kunit_test_suite() boilerplate, the conversion follows a number of patterns:
Test failures without cleanup. For example: if (!ptr) return -ENOMEM; Becomes: KUNIT_ASSERT_NOT_NULL(test, ptr);
In kunit ASSERT longjumps out of the test.
Check for error, fail and cleanup: if (err) { pr_err("msg\n"); goto cleanup; } Becomes: if (err) { KUNIT_FAIL(test, "msg"); goto cleanup; } Preserve the existing failure messages and cleanup code.
Cases where the test returns err but prints no message: if (err) goto cleanup; Becomes: if (err) { KUNIT_FAIL(test, "msg"); goto cleanup; } Use KUNIT_FAIL to retain the 'cleanup on err' behavior.
Overall, the conversion is straightforward.
The result can be run with kunit.py:
$ tools/testing/kunit/kunit.py run --build_dir build_kunit_x86_64 --arch x86_64 --kunitconfig ./drivers/dma-buf/.kunitconfig [20:37:23] Configuring KUnit Kernel ... [20:37:23] Building KUnit Kernel ... Populating config with: $ make ARCH=x86_64 O=build_kunit_x86_64 olddefconfig Building with: $ make all compile_commands.json scripts_gdb ARCH=x86_64 O=build_kunit_x86_64 --jobs=20 [20:37:29] Starting KUnit Kernel (1/1)... [20:37:29] ============================================================ Running tests with: $ qemu-system-x86_64 -nodefaults -m 1024 -kernel build_kunit_x86_64/arch/x86/boot/bzImage -append 'kunit.enable=1 console=ttyS0 kunit_shutdown=reboot' -no-reboot -nographic -accel kvm -accel hvf -accel tcg -serial stdio -bios qboot.rom [20:37:30] ================ dma-buf-resv (5 subtests) ================= [20:37:30] [PASSED] test_sanitycheck [20:37:30] ===================== test_signaling ====================== [20:37:30] [PASSED] kernel [20:37:30] [PASSED] write [20:37:30] [PASSED] read [20:37:30] [PASSED] bookkeep [20:37:30] ================= [PASSED] test_signaling ================== ... [20:37:35] Testing complete. Ran 50 tests: passed: 49, skipped: 1 [20:37:35] Elapsed time: 12.635s total, 0.001s configuring, 6.551s building, 6.017s running
One test that requires two CPUs is skipped since the default VM has a single CPU and cannot run the test.
All other usual ways to run kunit work as well, and all tests are placed in a module to provide more options for how they are run.
AI was used to do the large scale semantic search and replaces described above, then everything was hand checked. AI also deduced the issue with test_race_signal_callback() in a couple of seconds from the kunit crash (!!), again was hand checked though I am not so familiar with this test to be fully certain this is the best answer.
Jason Gunthorpe (5): dma-buf: Change st-dma-resv.c to use kunit dma-buf: Change st-dma-fence.c to use kunit dma-buf: Change st-dma-fence-unwrap.c to use kunit dma-buf: Change st-dma-fence-chain.c to use kunit dma-buf: Remove the old selftest
drivers/dma-buf/.kunitconfig | 2 + drivers/dma-buf/Kconfig | 11 +- drivers/dma-buf/Makefile | 5 +- drivers/dma-buf/selftest.c | 167 --------------- drivers/dma-buf/selftest.h | 30 --- drivers/dma-buf/selftests.h | 16 -- drivers/dma-buf/st-dma-fence-chain.c | 217 +++++++++---------- drivers/dma-buf/st-dma-fence-unwrap.c | 290 +++++++++++--------------- drivers/dma-buf/st-dma-fence.c | 200 ++++++++---------- drivers/dma-buf/st-dma-resv.c | 145 +++++++------ drivers/gpu/drm/i915/Kconfig.debug | 2 +- 11 files changed, 394 insertions(+), 691 deletions(-) create mode 100644 drivers/dma-buf/.kunitconfig delete mode 100644 drivers/dma-buf/selftest.c delete mode 100644 drivers/dma-buf/selftest.h delete mode 100644 drivers/dma-buf/selftests.h
base-commit: 41dae5ac5e157b0bb260f381eb3df2f4a4610205
Modernize the open coded test framework by using kunit.
The kunit tool can be used to build a kernel and run it in a VM with:
$ tools/testing/kunit/kunit.py run --build_dir build_kunit_x86_64 --arch x86_64 --kunitconfig ./drivers/dma-buf/.kunitconfig
Along with the other ways to run kunits.
To make the kunit tool work like this the DMABUF_KUNIT_TEST kconfig must select DMA_SHARED_BUFFER to get it turned on without building a driver using it.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/dma-buf/.kunitconfig | 2 + drivers/dma-buf/Kconfig | 8 ++ drivers/dma-buf/Makefile | 8 +- drivers/dma-buf/selftests.h | 1 - drivers/dma-buf/st-dma-resv.c | 145 +++++++++++++++++----------------- 5 files changed, 88 insertions(+), 76 deletions(-) create mode 100644 drivers/dma-buf/.kunitconfig
diff --git a/drivers/dma-buf/.kunitconfig b/drivers/dma-buf/.kunitconfig new file mode 100644 index 00000000000000..1ce5fb7e6cf9ff --- /dev/null +++ b/drivers/dma-buf/.kunitconfig @@ -0,0 +1,2 @@ +CONFIG_KUNIT=y +CONFIG_DMABUF_KUNIT_TEST=y diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index 8d4f2f89f24e3c..7d13c8f4484dd3 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -54,6 +54,14 @@ config DMABUF_SELFTESTS default n depends on DMA_SHARED_BUFFER
+config DMABUF_KUNIT_TEST + tristate "KUnit tests for DMA-BUF" if !KUNIT_ALL_TESTS + depends on KUNIT + select DMA_SHARED_BUFFER + default KUNIT_ALL_TESTS + help + Enable kunit tests for DMA-BUF + menuconfig DMABUF_HEAPS bool "DMA-BUF Userland Memory Heaps" select DMA_SHARED_BUFFER diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 7a85565d906ba1..2e7a1453e2fe04 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -11,7 +11,11 @@ dmabuf_selftests-y := \ selftest.o \ st-dma-fence.o \ st-dma-fence-chain.o \ - st-dma-fence-unwrap.o \ - st-dma-resv.o + st-dma-fence-unwrap.o
obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o + +dmabuf_kunit-y := \ + st-dma-resv.o + +obj-$(CONFIG_DMABUF_KUNIT_TEST) += dmabuf_kunit.o diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 851965867d9c7f..2fdaca6b3e92e2 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -13,4 +13,3 @@ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ selftest(dma_fence, dma_fence) selftest(dma_fence_chain, dma_fence_chain) selftest(dma_fence_unwrap, dma_fence_unwrap) -selftest(dma_resv, dma_resv) diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c index ad4dfb49dcd9fa..95a4becdb8926d 100644 --- a/drivers/dma-buf/st-dma-resv.c +++ b/drivers/dma-buf/st-dma-resv.c @@ -5,13 +5,17 @@ * Copyright © 2021 Advanced Micro Devices, Inc. */
+#include <kunit/test.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/dma-resv.h>
-#include "selftest.h" +static DEFINE_SPINLOCK(fence_lock);
-static struct spinlock fence_lock; +struct dma_resv_usage_param { + enum dma_resv_usage usage; + const char *desc; +};
static const char *fence_name(struct dma_fence *f) { @@ -35,15 +39,14 @@ static struct dma_fence *alloc_fence(void) return f; }
-static int sanitycheck(void *arg) +static void test_sanitycheck(struct kunit *test) { struct dma_resv resv; struct dma_fence *f; int r;
f = alloc_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
@@ -53,49 +56,46 @@ static int sanitycheck(void *arg) dma_resv_init(&resv); r = dma_resv_lock(&resv, NULL); if (r) - pr_err("Resv locking failed\n"); + KUNIT_FAIL(test, "Resv locking failed\n"); else dma_resv_unlock(&resv); dma_resv_fini(&resv); - return r; }
-static int test_signaling(void *arg) +static void test_signaling(struct kunit *test) { - enum dma_resv_usage usage = (unsigned long)arg; + const struct dma_resv_usage_param *param = test->param_value; + enum dma_resv_usage usage = param->usage; struct dma_resv resv; struct dma_fence *f; int r;
f = alloc_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); r = dma_resv_lock(&resv, NULL); if (r) { - pr_err("Resv locking failed\n"); + KUNIT_FAIL(test, "Resv locking failed"); goto err_free; }
r = dma_resv_reserve_fences(&resv, 1); if (r) { - pr_err("Resv shared slot allocation failed\n"); + KUNIT_FAIL(test, "Resv shared slot allocation failed"); goto err_unlock; }
dma_resv_add_fence(&resv, f, usage); if (dma_resv_test_signaled(&resv, usage)) { - pr_err("Resv unexpectedly signaled\n"); - r = -EINVAL; + KUNIT_FAIL(test, "Resv unexpectedly signaled"); goto err_unlock; } dma_fence_signal(f); if (!dma_resv_test_signaled(&resv, usage)) { - pr_err("Resv not reporting signaled\n"); - r = -EINVAL; + KUNIT_FAIL(test, "Resv not reporting signaled"); goto err_unlock; } err_unlock: @@ -103,33 +103,32 @@ static int test_signaling(void *arg) err_free: dma_resv_fini(&resv); dma_fence_put(f); - return r; }
-static int test_for_each(void *arg) +static void test_for_each(struct kunit *test) { - enum dma_resv_usage usage = (unsigned long)arg; + const struct dma_resv_usage_param *param = test->param_value; + enum dma_resv_usage usage = param->usage; struct dma_resv_iter cursor; struct dma_fence *f, *fence; struct dma_resv resv; int r;
f = alloc_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); r = dma_resv_lock(&resv, NULL); if (r) { - pr_err("Resv locking failed\n"); + KUNIT_FAIL(test, "Resv locking failed"); goto err_free; }
r = dma_resv_reserve_fences(&resv, 1); if (r) { - pr_err("Resv shared slot allocation failed\n"); + KUNIT_FAIL(test, "Resv shared slot allocation failed"); goto err_unlock; }
@@ -138,24 +137,23 @@ static int test_for_each(void *arg) r = -ENOENT; dma_resv_for_each_fence(&cursor, &resv, usage, fence) { if (!r) { - pr_err("More than one fence found\n"); - r = -EINVAL; + KUNIT_FAIL(test, "More than one fence found"); goto err_unlock; } if (f != fence) { - pr_err("Unexpected fence\n"); + KUNIT_FAIL(test, "Unexpected fence"); r = -EINVAL; goto err_unlock; } if (dma_resv_iter_usage(&cursor) != usage) { - pr_err("Unexpected fence usage\n"); + KUNIT_FAIL(test, "Unexpected fence usage"); r = -EINVAL; goto err_unlock; } r = 0; } if (r) { - pr_err("No fence found\n"); + KUNIT_FAIL(test, "No fence found"); goto err_unlock; } dma_fence_signal(f); @@ -164,33 +162,32 @@ static int test_for_each(void *arg) err_free: dma_resv_fini(&resv); dma_fence_put(f); - return r; }
-static int test_for_each_unlocked(void *arg) +static void test_for_each_unlocked(struct kunit *test) { - enum dma_resv_usage usage = (unsigned long)arg; + const struct dma_resv_usage_param *param = test->param_value; + enum dma_resv_usage usage = param->usage; struct dma_resv_iter cursor; struct dma_fence *f, *fence; struct dma_resv resv; int r;
f = alloc_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); r = dma_resv_lock(&resv, NULL); if (r) { - pr_err("Resv locking failed\n"); + KUNIT_FAIL(test, "Resv locking failed"); goto err_free; }
r = dma_resv_reserve_fences(&resv, 1); if (r) { - pr_err("Resv shared slot allocation failed\n"); + KUNIT_FAIL(test, "Resv shared slot allocation failed"); dma_resv_unlock(&resv); goto err_free; } @@ -202,21 +199,20 @@ static int test_for_each_unlocked(void *arg) dma_resv_iter_begin(&cursor, &resv, usage); dma_resv_for_each_fence_unlocked(&cursor, fence) { if (!r) { - pr_err("More than one fence found\n"); - r = -EINVAL; + KUNIT_FAIL(test, "More than one fence found"); goto err_iter_end; } if (!dma_resv_iter_is_restarted(&cursor)) { - pr_err("No restart flag\n"); + KUNIT_FAIL(test, "No restart flag"); goto err_iter_end; } if (f != fence) { - pr_err("Unexpected fence\n"); + KUNIT_FAIL(test, "Unexpected fence"); r = -EINVAL; goto err_iter_end; } if (dma_resv_iter_usage(&cursor) != usage) { - pr_err("Unexpected fence usage\n"); + KUNIT_FAIL(test, "Unexpected fence usage"); r = -EINVAL; goto err_iter_end; } @@ -230,40 +226,38 @@ static int test_for_each_unlocked(void *arg) r = 0; } } - if (r) - pr_err("No fence found\n"); + KUNIT_EXPECT_EQ(test, r, 0); err_iter_end: dma_resv_iter_end(&cursor); dma_fence_signal(f); err_free: dma_resv_fini(&resv); dma_fence_put(f); - return r; }
-static int test_get_fences(void *arg) +static void test_get_fences(struct kunit *test) { - enum dma_resv_usage usage = (unsigned long)arg; + const struct dma_resv_usage_param *param = test->param_value; + enum dma_resv_usage usage = param->usage; struct dma_fence *f, **fences = NULL; struct dma_resv resv; int r, i;
f = alloc_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_resv_init(&resv); r = dma_resv_lock(&resv, NULL); if (r) { - pr_err("Resv locking failed\n"); + KUNIT_FAIL(test, "Resv locking failed"); goto err_resv; }
r = dma_resv_reserve_fences(&resv, 1); if (r) { - pr_err("Resv shared slot allocation failed\n"); + KUNIT_FAIL(test, "Resv shared slot allocation failed"); dma_resv_unlock(&resv); goto err_resv; } @@ -273,12 +267,12 @@ static int test_get_fences(void *arg)
r = dma_resv_get_fences(&resv, usage, &i, &fences); if (r) { - pr_err("get_fences failed\n"); + KUNIT_FAIL(test, "get_fences failed"); goto err_free; }
if (i != 1 || fences[0] != f) { - pr_err("get_fences returned unexpected fence\n"); + KUNIT_FAIL(test, "get_fences returned unexpected fence"); goto err_free; }
@@ -290,27 +284,32 @@ static int test_get_fences(void *arg) err_resv: dma_resv_fini(&resv); dma_fence_put(f); - return r; }
-int dma_resv(void) -{ - static const struct subtest tests[] = { - SUBTEST(sanitycheck), - SUBTEST(test_signaling), - SUBTEST(test_for_each), - SUBTEST(test_for_each_unlocked), - SUBTEST(test_get_fences), - }; - enum dma_resv_usage usage; - int r; +static const struct dma_resv_usage_param dma_resv_usage_params[] = { + { DMA_RESV_USAGE_KERNEL, "kernel" }, + { DMA_RESV_USAGE_WRITE, "write" }, + { DMA_RESV_USAGE_READ, "read" }, + { DMA_RESV_USAGE_BOOKKEEP, "bookkeep" }, +};
- spin_lock_init(&fence_lock); - for (usage = DMA_RESV_USAGE_KERNEL; usage <= DMA_RESV_USAGE_BOOKKEEP; - ++usage) { - r = subtests(tests, (void *)(unsigned long)usage); - if (r) - return r; - } - return 0; -} +KUNIT_ARRAY_PARAM_DESC(dma_resv_usage, dma_resv_usage_params, desc); + +static struct kunit_case dma_resv_cases[] = { + KUNIT_CASE(test_sanitycheck), + KUNIT_CASE_PARAM(test_signaling, dma_resv_usage_gen_params), + KUNIT_CASE_PARAM(test_for_each, dma_resv_usage_gen_params), + KUNIT_CASE_PARAM(test_for_each_unlocked, dma_resv_usage_gen_params), + KUNIT_CASE_PARAM(test_get_fences, dma_resv_usage_gen_params), + {} +}; + +static struct kunit_suite dma_resv_test_suite = { + .name = "dma-buf-resv", + .test_cases = dma_resv_cases, +}; + +kunit_test_suite(dma_resv_test_suite); + +MODULE_DESCRIPTION("KUnit tests for DMA-BUF"); +MODULE_LICENSE("GPL");
Modernize the open coded test framework by using kunit.
Add a num_online_cpus() check to test_race_signal_callback() as the default kunit.py runs the VM with a single CPU and this test depends on two truly parallel kthreads. Skip it instead of hanging.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/dma-buf/Makefile | 2 +- drivers/dma-buf/selftests.h | 1 - drivers/dma-buf/st-dma-fence.c | 200 ++++++++++++++------------------- 3 files changed, 88 insertions(+), 115 deletions(-)
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 2e7a1453e2fe04..37c94562e677ca 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -9,13 +9,13 @@ obj-$(CONFIG_UDMABUF) += udmabuf.o
dmabuf_selftests-y := \ selftest.o \ - st-dma-fence.o \ st-dma-fence-chain.o \ st-dma-fence-unwrap.o
obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
dmabuf_kunit-y := \ + st-dma-fence.o \ st-dma-resv.o
obj-$(CONFIG_DMABUF_KUNIT_TEST) += dmabuf_kunit.o diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 2fdaca6b3e92e2..0a348a5cbbebc7 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -10,6 +10,5 @@ * Tests are executed in order by igt/dmabuf_selftest */ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ -selftest(dma_fence, dma_fence) selftest(dma_fence_chain, dma_fence_chain) selftest(dma_fence_unwrap, dma_fence_unwrap) diff --git a/drivers/dma-buf/st-dma-fence.c b/drivers/dma-buf/st-dma-fence.c index 0d9d524d79b6d9..4992722296968d 100644 --- a/drivers/dma-buf/st-dma-fence.c +++ b/drivers/dma-buf/st-dma-fence.c @@ -4,6 +4,7 @@ * Copyright © 2019 Intel Corporation */
+#include <kunit/test.h> #include <linux/delay.h> #include <linux/dma-fence.h> #include <linux/kernel.h> @@ -12,8 +13,6 @@ #include <linux/slab.h> #include <linux/spinlock.h>
-#include "selftest.h" - static const char *mock_name(struct dma_fence *f) { return "mock"; @@ -36,62 +35,55 @@ static struct dma_fence *mock_fence(void) return f; }
-static int sanitycheck(void *arg) +static void test_sanitycheck(struct kunit *test) { struct dma_fence *f;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_fence_signal(f); dma_fence_put(f); - - return 0; }
-static int test_signaling(void *arg) +static void test_signaling(struct kunit *test) { struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
if (dma_fence_is_signaled(f)) { - pr_err("Fence unexpectedly signaled on creation\n"); + KUNIT_FAIL(test, "Fence unexpectedly signaled on creation"); goto err_free; }
if (dma_fence_check_and_signal(f)) { - pr_err("Fence reported being already signaled\n"); + KUNIT_FAIL(test, "Fence reported being already signaled"); goto err_free; }
if (!dma_fence_is_signaled(f)) { - pr_err("Fence not reporting signaled\n"); + KUNIT_FAIL(test, "Fence not reporting signaled"); goto err_free; }
if (!dma_fence_test_signaled_flag(f)) { - pr_err("Fence reported not being already signaled\n"); + KUNIT_FAIL(test, "Fence reported not being already signaled"); goto err_free; }
if (rcu_dereference_protected(f->ops, true)) { - pr_err("Fence ops not cleared on signal\n"); + KUNIT_FAIL(test, "Fence ops not cleared on signal"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
struct simple_cb { @@ -104,215 +96,187 @@ static void simple_callback(struct dma_fence *f, struct dma_fence_cb *cb) smp_store_mb(container_of(cb, struct simple_cb, cb)->seen, true); }
-static int test_add_callback(void *arg) +static void test_add_callback(struct kunit *test) { struct simple_cb cb = {}; struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
if (dma_fence_add_callback(f, &cb.cb, simple_callback)) { - pr_err("Failed to add callback, fence already signaled!\n"); + KUNIT_FAIL(test, "Failed to add callback, fence already signaled!"); goto err_free; }
dma_fence_signal(f); if (!cb.seen) { - pr_err("Callback failed!\n"); + KUNIT_FAIL(test, "Callback failed!"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_late_add_callback(void *arg) +static void test_late_add_callback(struct kunit *test) { struct simple_cb cb = {}; struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_fence_signal(f);
if (!dma_fence_add_callback(f, &cb.cb, simple_callback)) { - pr_err("Added callback, but fence was already signaled!\n"); + KUNIT_FAIL(test, "Added callback, but fence was already signaled!"); goto err_free; }
dma_fence_signal(f); if (cb.seen) { - pr_err("Callback called after failed attachment !\n"); + KUNIT_FAIL(test, "Callback called after failed attachment!"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_rm_callback(void *arg) +static void test_rm_callback(struct kunit *test) { struct simple_cb cb = {}; struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
if (dma_fence_add_callback(f, &cb.cb, simple_callback)) { - pr_err("Failed to add callback, fence already signaled!\n"); + KUNIT_FAIL(test, "Failed to add callback, fence already signaled!"); goto err_free; }
if (!dma_fence_remove_callback(f, &cb.cb)) { - pr_err("Failed to remove callback!\n"); + KUNIT_FAIL(test, "Failed to remove callback!"); goto err_free; }
dma_fence_signal(f); if (cb.seen) { - pr_err("Callback still signaled after removal!\n"); + KUNIT_FAIL(test, "Callback still signaled after removal!"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_late_rm_callback(void *arg) +static void test_late_rm_callback(struct kunit *test) { struct simple_cb cb = {}; struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
if (dma_fence_add_callback(f, &cb.cb, simple_callback)) { - pr_err("Failed to add callback, fence already signaled!\n"); + KUNIT_FAIL(test, "Failed to add callback, fence already signaled!"); goto err_free; }
dma_fence_signal(f); if (!cb.seen) { - pr_err("Callback failed!\n"); + KUNIT_FAIL(test, "Callback failed!"); goto err_free; }
if (dma_fence_remove_callback(f, &cb.cb)) { - pr_err("Callback removal succeed after being executed!\n"); + KUNIT_FAIL(test, "Callback removal succeeded after being executed!"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_status(void *arg) +static void test_status(struct kunit *test) { struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
if (dma_fence_get_status(f)) { - pr_err("Fence unexpectedly has signaled status on creation\n"); + KUNIT_FAIL(test, "Fence unexpectedly has signaled status on creation"); goto err_free; }
dma_fence_signal(f); if (!dma_fence_get_status(f)) { - pr_err("Fence not reporting signaled status\n"); + KUNIT_FAIL(test, "Fence not reporting signaled status"); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_error(void *arg) +static void test_error(struct kunit *test) { struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
dma_fence_set_error(f, -EIO);
if (dma_fence_get_status(f)) { - pr_err("Fence unexpectedly has error status before signal\n"); + KUNIT_FAIL(test, "Fence unexpectedly has error status before signal"); goto err_free; }
dma_fence_signal(f); if (dma_fence_get_status(f) != -EIO) { - pr_err("Fence not reporting error status, got %d\n", - dma_fence_get_status(f)); + KUNIT_FAIL(test, "Fence not reporting error status, got %d", + dma_fence_get_status(f)); goto err_free; }
- err = 0; err_free: dma_fence_put(f); - return err; }
-static int test_wait(void *arg) +static void test_wait(struct kunit *test) { struct dma_fence *f; - int err = -EINVAL;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
if (dma_fence_wait_timeout(f, false, 0) != 0) { - pr_err("Wait reported complete before being signaled\n"); + KUNIT_FAIL(test, "Wait reported complete before being signaled"); goto err_free; }
dma_fence_signal(f);
if (dma_fence_wait_timeout(f, false, 0) != 1) { - pr_err("Wait reported incomplete after being signaled\n"); + KUNIT_FAIL(test, "Wait reported incomplete after being signaled"); goto err_free; }
- err = 0; err_free: dma_fence_signal(f); dma_fence_put(f); - return err; }
struct wait_timer { @@ -327,21 +291,19 @@ static void wait_timer(struct timer_list *timer) dma_fence_signal(wt->f); }
-static int test_wait_timeout(void *arg) +static void test_wait_timeout(struct kunit *test) { struct wait_timer wt; - int err = -EINVAL;
timer_setup_on_stack(&wt.timer, wait_timer, 0);
wt.f = mock_fence(); - if (!wt.f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, wt.f);
dma_fence_enable_sw_signaling(wt.f);
if (dma_fence_wait_timeout(wt.f, false, 1) != 0) { - pr_err("Wait reported complete before being signaled\n"); + KUNIT_FAIL(test, "Wait reported complete before being signaled"); goto err_free; }
@@ -349,42 +311,38 @@ static int test_wait_timeout(void *arg)
if (dma_fence_wait_timeout(wt.f, false, HZ) == 0) { if (timer_pending(&wt.timer)) { - pr_notice("Timer did not fire within one HZ!\n"); - err = 0; /* not our fault! */ + kunit_mark_skipped( + test, "Timer did not fire within on HZ!\n"); } else { - pr_err("Wait reported incomplete after timeout\n"); + KUNIT_FAIL(test, + "Wait reported incomplete after timeout"); } goto err_free; }
- err = 0; err_free: timer_delete_sync(&wt.timer); timer_destroy_on_stack(&wt.timer); dma_fence_signal(wt.f); dma_fence_put(wt.f); - return err; }
-static int test_stub(void *arg) +static void test_stub(struct kunit *test) { struct dma_fence *f[64]; - int err = -EINVAL; int i;
for (i = 0; i < ARRAY_SIZE(f); i++) { f[i] = dma_fence_get_stub(); if (!dma_fence_is_signaled(f[i])) { - pr_err("Obtained unsignaled stub fence!\n"); + KUNIT_FAIL(test, "Obtained unsignaled stub fence!"); goto err; } }
- err = 0; err: while (i--) dma_fence_put(f[i]); - return err; }
/* Now off to the races! */ @@ -473,12 +431,19 @@ static int thread_signal_callback(void *arg) return err; }
-static int race_signal_callback(void *arg) +static void test_race_signal_callback(struct kunit *test) { struct dma_fence __rcu *f[2] = {}; int ret = 0; int pass;
+ /* + * thread_signal_callback() spins under RCU and it cannot make forward + * progress unless the threads are truly running concurrently. + */ + if (num_online_cpus() < 2) + kunit_skip(test, "requires at least 2 CPUs"); + for (pass = 0; !ret && pass <= 1; pass++) { struct race_thread t[2]; int i; @@ -490,10 +455,10 @@ static int race_signal_callback(void *arg) t[i].task = kthread_run(thread_signal_callback, &t[i], "dma-fence:%d", i); if (IS_ERR(t[i].task)) { - ret = PTR_ERR(t[i].task); + KUNIT_FAIL(test, "Failed to create kthread"); while (--i >= 0) kthread_stop_put(t[i].task); - return ret; + return; } get_task_struct(t[i].task); } @@ -509,26 +474,35 @@ static int race_signal_callback(void *arg) } }
- return ret; + KUNIT_EXPECT_EQ(test, ret, 0); }
-int dma_fence(void) +static int dma_fence_suite_init(struct kunit_suite *suite) { - static const struct subtest tests[] = { - SUBTEST(sanitycheck), - SUBTEST(test_signaling), - SUBTEST(test_add_callback), - SUBTEST(test_late_add_callback), - SUBTEST(test_rm_callback), - SUBTEST(test_late_rm_callback), - SUBTEST(test_status), - SUBTEST(test_error), - SUBTEST(test_wait), - SUBTEST(test_wait_timeout), - SUBTEST(test_stub), - SUBTEST(race_signal_callback), - }; - pr_info("sizeof(dma_fence)=%zu\n", sizeof(struct dma_fence)); - return subtests(tests, NULL); + return 0; } + +static struct kunit_case dma_fence_cases[] = { + KUNIT_CASE(test_sanitycheck), + KUNIT_CASE(test_signaling), + KUNIT_CASE(test_add_callback), + KUNIT_CASE(test_late_add_callback), + KUNIT_CASE(test_rm_callback), + KUNIT_CASE(test_late_rm_callback), + KUNIT_CASE(test_status), + KUNIT_CASE(test_error), + KUNIT_CASE(test_wait), + KUNIT_CASE(test_wait_timeout), + KUNIT_CASE(test_stub), + KUNIT_CASE(test_race_signal_callback), + {} +}; + +static struct kunit_suite dma_fence_test_suite = { + .name = "dma-buf-fence", + .suite_init = dma_fence_suite_init, + .test_cases = dma_fence_cases, +}; + +kunit_test_suite(dma_fence_test_suite);
Modernize the open coded test framework by using kunit.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/dma-buf/Makefile | 4 +- drivers/dma-buf/selftests.h | 1 - drivers/dma-buf/st-dma-fence-unwrap.c | 290 +++++++++++--------------- 3 files changed, 129 insertions(+), 166 deletions(-)
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 37c94562e677ca..65bda1b7cc73eb 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -9,13 +9,13 @@ obj-$(CONFIG_UDMABUF) += udmabuf.o
dmabuf_selftests-y := \ selftest.o \ - st-dma-fence-chain.o \ - st-dma-fence-unwrap.o + st-dma-fence-chain.o
obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
dmabuf_kunit-y := \ st-dma-fence.o \ + st-dma-fence-unwrap.o \ st-dma-resv.o
obj-$(CONFIG_DMABUF_KUNIT_TEST) += dmabuf_kunit.o diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 0a348a5cbbebc7..7104cf0cce26d1 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -11,4 +11,3 @@ */ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ selftest(dma_fence_chain, dma_fence_chain) -selftest(dma_fence_unwrap, dma_fence_unwrap) diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index 9c74195f47fd33..51c87869b7b82c 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -4,13 +4,12 @@ * Copyright (C) 2022 Advanced Micro Devices, Inc. */
+#include <kunit/test.h> #include <linux/dma-fence.h> #include <linux/dma-fence-array.h> #include <linux/dma-fence-chain.h> #include <linux/dma-fence-unwrap.h>
-#include "selftest.h" - #define CHAIN_SZ (4 << 10)
struct mock_fence { @@ -97,52 +96,45 @@ static struct dma_fence *mock_chain(struct dma_fence *prev, return &f->base; }
-static int sanitycheck(void *arg) +static void test_sanitycheck(struct kunit *test) { struct dma_fence *f, *chain, *array; - int err = 0;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
dma_fence_enable_sw_signaling(f);
array = mock_array(1, f); - if (!array) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, array);
chain = mock_chain(NULL, array); - if (!chain) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, chain);
dma_fence_put(chain); - return err; }
-static int unwrap_array(void *arg) +static void test_unwrap_array(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *array; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); dma_fence_put(f1); - return -ENOMEM; + return; }
dma_fence_enable_sw_signaling(f2);
array = mock_array(2, f1, f2); - if (!array) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, array);
dma_fence_unwrap_for_each(fence, &iter, array) { if (fence == f1) { @@ -150,43 +142,37 @@ static int unwrap_array(void *arg) } else if (fence == f2) { f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(array); - return err; }
-static int unwrap_chain(void *arg) +static void test_unwrap_chain(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *chain; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); dma_fence_put(f1); - return -ENOMEM; + return; }
dma_fence_enable_sw_signaling(f2);
chain = mock_chain(f1, f2); - if (!chain) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, chain);
dma_fence_unwrap_for_each(fence, &iter, chain) { if (fence == f1) { @@ -194,47 +180,40 @@ static int unwrap_chain(void *arg) } else if (fence == f2) { f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(chain); - return err; }
-static int unwrap_chain_array(void *arg) +static void test_unwrap_chain_array(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *array, *chain; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); dma_fence_put(f1); - return -ENOMEM; + return; }
dma_fence_enable_sw_signaling(f2);
array = mock_array(2, f1, f2); - if (!array) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, array);
chain = mock_chain(NULL, array); - if (!chain) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, chain);
dma_fence_unwrap_for_each(fence, &iter, chain) { if (fence == f1) { @@ -242,35 +221,29 @@ static int unwrap_chain_array(void *arg) } else if (fence == f2) { f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(chain); - return err; }
-static int unwrap_merge(void *arg) +static void test_unwrap_merge(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *f3; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); if (!f2) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f1; }
@@ -278,7 +251,7 @@ static int unwrap_merge(void *arg)
f3 = dma_fence_unwrap_merge(f1, f2); if (!f3) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f2; }
@@ -290,39 +263,33 @@ static int unwrap_merge(void *arg) dma_fence_put(f2); f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(f3); error_put_f2: dma_fence_put(f2); error_put_f1: dma_fence_put(f1); - return err; }
-static int unwrap_merge_duplicate(void *arg) +static void test_unwrap_merge_duplicate(struct kunit *test) { struct dma_fence *fence, *f1, *f2; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = dma_fence_unwrap_merge(f1, f1); if (!f2) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f1; }
@@ -331,41 +298,35 @@ static int unwrap_merge_duplicate(void *arg) dma_fence_put(f1); f1 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(f2); error_put_f1: dma_fence_put(f1); - return err; }
-static int unwrap_merge_seqno(void *arg) +static void test_unwrap_merge_seqno(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *f3, *f4; struct dma_fence_unwrap iter; - int err = 0; u64 ctx[2];
ctx[0] = dma_fence_context_alloc(1); ctx[1] = dma_fence_context_alloc(1);
f1 = __mock_fence(ctx[1], 1); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = __mock_fence(ctx[1], 2); if (!f2) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f1; }
@@ -373,7 +334,7 @@ static int unwrap_merge_seqno(void *arg)
f3 = __mock_fence(ctx[0], 1); if (!f3) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f2; }
@@ -381,7 +342,7 @@ static int unwrap_merge_seqno(void *arg)
f4 = dma_fence_unwrap_merge(f1, f2, f3); if (!f4) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f3; }
@@ -393,15 +354,12 @@ static int unwrap_merge_seqno(void *arg) dma_fence_put(f2); f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f2 || f3) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f2 || f3) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(f4); error_put_f3: @@ -410,40 +368,41 @@ static int unwrap_merge_seqno(void *arg) dma_fence_put(f2); error_put_f1: dma_fence_put(f1); - return err; }
-static int unwrap_merge_order(void *arg) +static void test_unwrap_merge_order(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *a1, *a2, *c1, *c2; struct dma_fence_unwrap iter; - int err = 0;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); dma_fence_put(f1); - return -ENOMEM; + return; }
dma_fence_enable_sw_signaling(f2);
a1 = mock_array(2, f1, f2); - if (!a1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, a1);
c1 = mock_chain(NULL, dma_fence_get(f1)); - if (!c1) + if (!c1) { + KUNIT_FAIL(test, "Failed to create chain"); goto error_put_a1; + }
c2 = mock_chain(c1, dma_fence_get(f2)); - if (!c2) + if (!c2) { + KUNIT_FAIL(test, "Failed to create chain"); goto error_put_a1; + }
/* * The fences in the chain are the same as in a1 but in oposite order, @@ -455,63 +414,64 @@ static int unwrap_merge_order(void *arg) if (fence == f1) { f1 = NULL; if (!f2) - pr_err("Unexpected order!\n"); + KUNIT_FAIL(test, "Unexpected order!"); } else if (fence == f2) { f2 = NULL; if (f1) - pr_err("Unexpected order!\n"); + KUNIT_FAIL(test, "Unexpected order!"); } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(a2); - return err; + return;
error_put_a1: dma_fence_put(a1); - return -ENOMEM; }
-static int unwrap_merge_complex(void *arg) +static void test_unwrap_merge_complex(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *f3, *f4, *f5; struct dma_fence_unwrap iter; - int err = -ENOMEM;
f1 = mock_fence(); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = mock_fence(); - if (!f2) + if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f1; + }
dma_fence_enable_sw_signaling(f2);
f3 = dma_fence_unwrap_merge(f1, f2); - if (!f3) + if (!f3) { + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f2; + }
/* The resulting array has the fences in reverse */ f4 = mock_array(2, dma_fence_get(f2), dma_fence_get(f1)); - if (!f4) + if (!f4) { + KUNIT_FAIL(test, "Failed to create array"); goto error_put_f3; + }
/* Signaled fences should be filtered, the two arrays merged. */ f5 = dma_fence_unwrap_merge(f3, f4, dma_fence_get_stub()); - if (!f5) + if (!f5) { + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f4; + }
- err = 0; dma_fence_unwrap_for_each(fence, &iter, f5) { if (fence == f1) { dma_fence_put(f1); @@ -520,15 +480,12 @@ static int unwrap_merge_complex(void *arg) dma_fence_put(f2); f2 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f2) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f2) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(f5); error_put_f4: @@ -539,56 +496,64 @@ static int unwrap_merge_complex(void *arg) dma_fence_put(f2); error_put_f1: dma_fence_put(f1); - return err; }
-static int unwrap_merge_complex_seqno(void *arg) +static void test_unwrap_merge_complex_seqno(struct kunit *test) { struct dma_fence *fence, *f1, *f2, *f3, *f4, *f5, *f6, *f7; struct dma_fence_unwrap iter; - int err = -ENOMEM; u64 ctx[2];
ctx[0] = dma_fence_context_alloc(1); ctx[1] = dma_fence_context_alloc(1);
f1 = __mock_fence(ctx[0], 2); - if (!f1) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f1);
dma_fence_enable_sw_signaling(f1);
f2 = __mock_fence(ctx[1], 1); - if (!f2) + if (!f2) { + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f1; + }
dma_fence_enable_sw_signaling(f2);
f3 = __mock_fence(ctx[0], 1); - if (!f3) + if (!f3) { + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f2; + }
dma_fence_enable_sw_signaling(f3);
f4 = __mock_fence(ctx[1], 2); - if (!f4) + if (!f4) { + KUNIT_FAIL(test, "Failed to create mock fence"); goto error_put_f3; + }
dma_fence_enable_sw_signaling(f4);
f5 = mock_array(2, dma_fence_get(f1), dma_fence_get(f2)); - if (!f5) + if (!f5) { + KUNIT_FAIL(test, "Failed to create array"); goto error_put_f4; + }
f6 = mock_array(2, dma_fence_get(f3), dma_fence_get(f4)); - if (!f6) + if (!f6) { + KUNIT_FAIL(test, "Failed to create array"); goto error_put_f5; + }
f7 = dma_fence_unwrap_merge(f5, f6); - if (!f7) + if (!f7) { + KUNIT_FAIL(test, "Failed to merge fences"); goto error_put_f6; + }
- err = 0; dma_fence_unwrap_for_each(fence, &iter, f7) { if (fence == f1 && f4) { dma_fence_put(f1); @@ -597,15 +562,12 @@ static int unwrap_merge_complex_seqno(void *arg) dma_fence_put(f4); f4 = NULL; } else { - pr_err("Unexpected fence!\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Unexpected fence!"); } }
- if (f1 || f4) { - pr_err("Not all fences seen!\n"); - err = -EINVAL; - } + if (f1 || f4) + KUNIT_FAIL(test, "Not all fences seen!");
dma_fence_put(f7); error_put_f6: @@ -620,23 +582,25 @@ static int unwrap_merge_complex_seqno(void *arg) dma_fence_put(f2); error_put_f1: dma_fence_put(f1); - return err; }
-int dma_fence_unwrap(void) -{ - static const struct subtest tests[] = { - SUBTEST(sanitycheck), - SUBTEST(unwrap_array), - SUBTEST(unwrap_chain), - SUBTEST(unwrap_chain_array), - SUBTEST(unwrap_merge), - SUBTEST(unwrap_merge_duplicate), - SUBTEST(unwrap_merge_seqno), - SUBTEST(unwrap_merge_order), - SUBTEST(unwrap_merge_complex), - SUBTEST(unwrap_merge_complex_seqno), - }; +static struct kunit_case dma_fence_unwrap_cases[] = { + KUNIT_CASE(test_sanitycheck), + KUNIT_CASE(test_unwrap_array), + KUNIT_CASE(test_unwrap_chain), + KUNIT_CASE(test_unwrap_chain_array), + KUNIT_CASE(test_unwrap_merge), + KUNIT_CASE(test_unwrap_merge_duplicate), + KUNIT_CASE(test_unwrap_merge_seqno), + KUNIT_CASE(test_unwrap_merge_order), + KUNIT_CASE(test_unwrap_merge_complex), + KUNIT_CASE(test_unwrap_merge_complex_seqno), + {} +};
- return subtests(tests, NULL); -} +static struct kunit_suite dma_fence_unwrap_test_suite = { + .name = "dma-buf-fence-unwrap", + .test_cases = dma_fence_unwrap_cases, +}; + +kunit_test_suite(dma_fence_unwrap_test_suite);
Modernize the open coded test framework by using kunit.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/dma-buf/Makefile | 4 +- drivers/dma-buf/selftests.h | 1 - drivers/dma-buf/st-dma-fence-chain.c | 217 ++++++++++++--------------- 3 files changed, 98 insertions(+), 124 deletions(-)
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 65bda1b7cc73eb..c97ab2d01a7e68 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -8,13 +8,13 @@ obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o obj-$(CONFIG_UDMABUF) += udmabuf.o
dmabuf_selftests-y := \ - selftest.o \ - st-dma-fence-chain.o + selftest.o
obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o
dmabuf_kunit-y := \ st-dma-fence.o \ + st-dma-fence-chain.o \ st-dma-fence-unwrap.o \ st-dma-resv.o
diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h index 7104cf0cce26d1..37b7251841278e 100644 --- a/drivers/dma-buf/selftests.h +++ b/drivers/dma-buf/selftests.h @@ -10,4 +10,3 @@ * Tests are executed in order by igt/dmabuf_selftest */ selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ -selftest(dma_fence_chain, dma_fence_chain) diff --git a/drivers/dma-buf/st-dma-fence-chain.c b/drivers/dma-buf/st-dma-fence-chain.c index 821023dd34df68..a3023d3fedc9d8 100644 --- a/drivers/dma-buf/st-dma-fence-chain.c +++ b/drivers/dma-buf/st-dma-fence-chain.c @@ -4,6 +4,7 @@ * Copyright © 2019 Intel Corporation */
+#include <kunit/test.h> #include <linux/delay.h> #include <linux/dma-fence.h> #include <linux/dma-fence-chain.h> @@ -15,8 +16,6 @@ #include <linux/spinlock.h> #include <linux/random.h>
-#include "selftest.h" - #define CHAIN_SZ (4 << 10)
static struct kmem_cache *slab_fences; @@ -74,27 +73,23 @@ static struct dma_fence *mock_chain(struct dma_fence *prev, return &f->base; }
-static int sanitycheck(void *arg) +static void test_sanitycheck(struct kunit *test) { struct dma_fence *f, *chain; - int err = 0;
f = mock_fence(); - if (!f) - return -ENOMEM; + KUNIT_ASSERT_NOT_NULL(test, f);
chain = mock_chain(NULL, f, 1); if (chain) dma_fence_enable_sw_signaling(chain); else - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to create chain");
dma_fence_signal(f); dma_fence_put(f);
dma_fence_put(chain); - - return err; }
struct fence_chains { @@ -176,7 +171,7 @@ static void fence_chains_fini(struct fence_chains *fc) kvfree(fc->chains); }
-static int find_seqno(void *arg) +static void test_find_seqno(struct kunit *test) { struct fence_chains fc; struct dma_fence *fence; @@ -184,14 +179,13 @@ static int find_seqno(void *arg) int i;
err = fence_chains_init(&fc, 64, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
fence = dma_fence_get(fc.tail); err = dma_fence_chain_find_seqno(&fence, 0); dma_fence_put(fence); if (err) { - pr_err("Reported %d for find_seqno(0)!\n", err); + KUNIT_FAIL(test, "Reported %d for find_seqno(0)!", err); goto err; }
@@ -200,14 +194,13 @@ static int find_seqno(void *arg) err = dma_fence_chain_find_seqno(&fence, i + 1); dma_fence_put(fence); if (err) { - pr_err("Reported %d for find_seqno(%d:%d)!\n", - err, fc.chain_length + 1, i + 1); + KUNIT_FAIL(test, "Reported %d for find_seqno(%d:%d)!", + err, fc.chain_length + 1, i + 1); goto err; } if (fence != fc.chains[i]) { - pr_err("Incorrect fence reported by find_seqno(%d:%d)\n", - fc.chain_length + 1, i + 1); - err = -EINVAL; + KUNIT_FAIL(test, "Incorrect fence reported by find_seqno(%d:%d)", + fc.chain_length + 1, i + 1); goto err; }
@@ -215,12 +208,11 @@ static int find_seqno(void *arg) err = dma_fence_chain_find_seqno(&fence, i + 1); dma_fence_put(fence); if (err) { - pr_err("Error reported for finding self\n"); + KUNIT_FAIL(test, "Error reported for finding self"); goto err; } if (fence != fc.chains[i]) { - pr_err("Incorrect fence reported by find self\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Incorrect fence reported by find self"); goto err; }
@@ -228,9 +220,8 @@ static int find_seqno(void *arg) err = dma_fence_chain_find_seqno(&fence, i + 2); dma_fence_put(fence); if (!err) { - pr_err("Error not reported for future fence: find_seqno(%d:%d)!\n", - i + 1, i + 2); - err = -EINVAL; + KUNIT_FAIL(test, "Error not reported for future fence: find_seqno(%d:%d)!", + i + 1, i + 2); goto err; }
@@ -238,31 +229,28 @@ static int find_seqno(void *arg) err = dma_fence_chain_find_seqno(&fence, i); dma_fence_put(fence); if (err) { - pr_err("Error reported for previous fence!\n"); + KUNIT_FAIL(test, "Error reported for previous fence!"); goto err; } if (i > 0 && fence != fc.chains[i - 1]) { - pr_err("Incorrect fence reported by find_seqno(%d:%d)\n", - i + 1, i); - err = -EINVAL; + KUNIT_FAIL(test, "Incorrect fence reported by find_seqno(%d:%d)", + i + 1, i); goto err; } }
err: fence_chains_fini(&fc); - return err; }
-static int find_signaled(void *arg) +static void test_find_signaled(struct kunit *test) { struct fence_chains fc; struct dma_fence *fence; int err;
err = fence_chains_init(&fc, 2, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
dma_fence_signal(fc.fences[0]);
@@ -270,37 +258,33 @@ static int find_signaled(void *arg) err = dma_fence_chain_find_seqno(&fence, 1); dma_fence_put(fence); if (err) { - pr_err("Reported %d for find_seqno()!\n", err); + KUNIT_FAIL(test, "Reported %d for find_seqno()!", err); goto err; }
if (fence && fence != fc.chains[0]) { - pr_err("Incorrect chain-fence.seqno:%lld reported for completed seqno:1\n", - fence->seqno); + KUNIT_FAIL(test, "Incorrect chain-fence.seqno:%lld reported for completed seqno:1", + fence->seqno);
dma_fence_get(fence); err = dma_fence_chain_find_seqno(&fence, 1); dma_fence_put(fence); if (err) - pr_err("Reported %d for finding self!\n", err); - - err = -EINVAL; + KUNIT_FAIL(test, "Reported %d for finding self!", err); }
err: fence_chains_fini(&fc); - return err; }
-static int find_out_of_order(void *arg) +static void test_find_out_of_order(struct kunit *test) { struct fence_chains fc; struct dma_fence *fence; int err;
err = fence_chains_init(&fc, 3, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
dma_fence_signal(fc.fences[1]);
@@ -308,7 +292,7 @@ static int find_out_of_order(void *arg) err = dma_fence_chain_find_seqno(&fence, 2); dma_fence_put(fence); if (err) { - pr_err("Reported %d for find_seqno()!\n", err); + KUNIT_FAIL(test, "Reported %d for find_seqno()!", err); goto err; }
@@ -319,16 +303,12 @@ static int find_out_of_order(void *arg) * we should get as fence to wait upon (fence 2 being garbage * collected during the traversal of the chain). */ - if (fence != fc.chains[0]) { - pr_err("Incorrect chain-fence.seqno:%lld reported for completed seqno:2\n", - fence ? fence->seqno : 0); - - err = -EINVAL; - } + if (fence != fc.chains[0]) + KUNIT_FAIL(test, "Incorrect chain-fence.seqno:%lld reported for completed seqno:2", + fence ? fence->seqno : 0);
err: fence_chains_fini(&fc); - return err; }
static uint64_t seqno_inc2(unsigned int i) @@ -336,7 +316,7 @@ static uint64_t seqno_inc2(unsigned int i) return 2 * i + 2; }
-static int find_gap(void *arg) +static void test_find_gap(struct kunit *test) { struct fence_chains fc; struct dma_fence *fence; @@ -344,24 +324,22 @@ static int find_gap(void *arg) int i;
err = fence_chains_init(&fc, 64, seqno_inc2); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
for (i = 0; i < fc.chain_length; i++) { fence = dma_fence_get(fc.tail); err = dma_fence_chain_find_seqno(&fence, 2 * i + 1); dma_fence_put(fence); if (err) { - pr_err("Reported %d for find_seqno(%d:%d)!\n", - err, fc.chain_length + 1, 2 * i + 1); + KUNIT_FAIL(test, "Reported %d for find_seqno(%d:%d)!", + err, fc.chain_length + 1, 2 * i + 1); goto err; } if (fence != fc.chains[i]) { - pr_err("Incorrect fence.seqno:%lld reported by find_seqno(%d:%d)\n", - fence->seqno, - fc.chain_length + 1, - 2 * i + 1); - err = -EINVAL; + KUNIT_FAIL(test, "Incorrect fence.seqno:%lld reported by find_seqno(%d:%d)", + fence->seqno, + fc.chain_length + 1, + 2 * i + 1); goto err; }
@@ -369,19 +347,17 @@ static int find_gap(void *arg) err = dma_fence_chain_find_seqno(&fence, 2 * i + 2); dma_fence_put(fence); if (err) { - pr_err("Error reported for finding self\n"); + KUNIT_FAIL(test, "Error reported for finding self"); goto err; } if (fence != fc.chains[i]) { - pr_err("Incorrect fence reported by find self\n"); - err = -EINVAL; + KUNIT_FAIL(test, "Incorrect fence reported by find self"); goto err; } }
err: fence_chains_fini(&fc); - return err; }
struct find_race { @@ -437,7 +413,7 @@ static int __find_race(void *arg) return err; }
-static int find_race(void *arg) +static void test_find_race(struct kunit *test) { struct find_race data; int ncpus = num_online_cpus(); @@ -447,12 +423,11 @@ static int find_race(void *arg) int i;
err = fence_chains_init(&data.fc, CHAIN_SZ, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
threads = kmalloc_objs(*threads, ncpus); if (!threads) { - err = -ENOMEM; + KUNIT_FAIL(test, "Failed to allocate threads array"); goto err; }
@@ -486,74 +461,67 @@ static int find_race(void *arg) count++; pr_info("Completed %lu cycles\n", count);
+ KUNIT_EXPECT_EQ(test, err, 0); + err: fence_chains_fini(&data.fc); - return err; }
-static int signal_forward(void *arg) +static void test_signal_forward(struct kunit *test) { struct fence_chains fc; int err; int i;
err = fence_chains_init(&fc, 64, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
for (i = 0; i < fc.chain_length; i++) { dma_fence_signal(fc.fences[i]);
if (!dma_fence_is_signaled(fc.chains[i])) { - pr_err("chain[%d] not signaled!\n", i); - err = -EINVAL; + KUNIT_FAIL(test, "chain[%d] not signaled!", i); goto err; }
if (i + 1 < fc.chain_length && dma_fence_is_signaled(fc.chains[i + 1])) { - pr_err("chain[%d] is signaled!\n", i); - err = -EINVAL; + KUNIT_FAIL(test, "chain[%d] is signaled!", i); goto err; } }
err: fence_chains_fini(&fc); - return err; }
-static int signal_backward(void *arg) +static void test_signal_backward(struct kunit *test) { struct fence_chains fc; int err; int i;
err = fence_chains_init(&fc, 64, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
for (i = fc.chain_length; i--; ) { dma_fence_signal(fc.fences[i]);
if (i > 0 && dma_fence_is_signaled(fc.chains[i])) { - pr_err("chain[%d] is signaled!\n", i); - err = -EINVAL; + KUNIT_FAIL(test, "chain[%d] is signaled!", i); goto err; } }
for (i = 0; i < fc.chain_length; i++) { if (!dma_fence_is_signaled(fc.chains[i])) { - pr_err("chain[%d] was not signaled!\n", i); - err = -EINVAL; + KUNIT_FAIL(test, "chain[%d] was not signaled!", i); goto err; } }
err: fence_chains_fini(&fc); - return err; }
static int __wait_fence_chains(void *arg) @@ -566,7 +534,7 @@ static int __wait_fence_chains(void *arg) return 0; }
-static int wait_forward(void *arg) +static void test_wait_forward(struct kunit *test) { struct fence_chains fc; struct task_struct *tsk; @@ -574,12 +542,11 @@ static int wait_forward(void *arg) int i;
err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait"); if (IS_ERR(tsk)) { - err = PTR_ERR(tsk); + KUNIT_FAIL(test, "Failed to create kthread"); goto err; } get_task_struct(tsk); @@ -589,13 +556,13 @@ static int wait_forward(void *arg) dma_fence_signal(fc.fences[i]);
err = kthread_stop_put(tsk); + KUNIT_EXPECT_EQ(test, err, 0);
err: fence_chains_fini(&fc); - return err; }
-static int wait_backward(void *arg) +static void test_wait_backward(struct kunit *test) { struct fence_chains fc; struct task_struct *tsk; @@ -603,12 +570,11 @@ static int wait_backward(void *arg) int i;
err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait"); if (IS_ERR(tsk)) { - err = PTR_ERR(tsk); + KUNIT_FAIL(test, "Failed to create kthread"); goto err; } get_task_struct(tsk); @@ -618,10 +584,10 @@ static int wait_backward(void *arg) dma_fence_signal(fc.fences[i]);
err = kthread_stop_put(tsk); + KUNIT_EXPECT_EQ(test, err, 0);
err: fence_chains_fini(&fc); - return err; }
static void randomise_fences(struct fence_chains *fc) @@ -640,7 +606,7 @@ static void randomise_fences(struct fence_chains *fc) } }
-static int wait_random(void *arg) +static void test_wait_random(struct kunit *test) { struct fence_chains fc; struct task_struct *tsk; @@ -648,14 +614,13 @@ static int wait_random(void *arg) int i;
err = fence_chains_init(&fc, CHAIN_SZ, seqno_inc); - if (err) - return err; + KUNIT_ASSERT_EQ_MSG(test, err, 0, "Failed to init fence chains");
randomise_fences(&fc);
tsk = kthread_run(__wait_fence_chains, &fc, "dmabuf/wait"); if (IS_ERR(tsk)) { - err = PTR_ERR(tsk); + KUNIT_FAIL(test, "Failed to create kthread"); goto err; } get_task_struct(tsk); @@ -665,29 +630,14 @@ static int wait_random(void *arg) dma_fence_signal(fc.fences[i]);
err = kthread_stop_put(tsk); + KUNIT_EXPECT_EQ(test, err, 0);
err: fence_chains_fini(&fc); - return err; }
-int dma_fence_chain(void) +static int dma_fence_chain_suite_init(struct kunit_suite *suite) { - static const struct subtest tests[] = { - SUBTEST(sanitycheck), - SUBTEST(find_seqno), - SUBTEST(find_signaled), - SUBTEST(find_out_of_order), - SUBTEST(find_gap), - SUBTEST(find_race), - SUBTEST(signal_forward), - SUBTEST(signal_backward), - SUBTEST(wait_forward), - SUBTEST(wait_backward), - SUBTEST(wait_random), - }; - int ret; - pr_info("sizeof(dma_fence_chain)=%zu\n", sizeof(struct dma_fence_chain));
@@ -696,9 +646,34 @@ int dma_fence_chain(void) SLAB_HWCACHE_ALIGN); if (!slab_fences) return -ENOMEM; - - ret = subtests(tests, NULL); - - kmem_cache_destroy(slab_fences); - return ret; + return 0; } + +static void dma_fence_chain_suite_exit(struct kunit_suite *suite) +{ + kmem_cache_destroy(slab_fences); +} + +static struct kunit_case dma_fence_chain_cases[] = { + KUNIT_CASE(test_sanitycheck), + KUNIT_CASE(test_find_seqno), + KUNIT_CASE(test_find_signaled), + KUNIT_CASE(test_find_out_of_order), + KUNIT_CASE(test_find_gap), + KUNIT_CASE(test_find_race), + KUNIT_CASE(test_signal_forward), + KUNIT_CASE(test_signal_backward), + KUNIT_CASE(test_wait_forward), + KUNIT_CASE(test_wait_backward), + KUNIT_CASE(test_wait_random), + {} +}; + +static struct kunit_suite dma_fence_chain_test_suite = { + .name = "dma-buf-fence-chain", + .suite_init = dma_fence_chain_suite_init, + .suite_exit = dma_fence_chain_suite_exit, + .test_cases = dma_fence_chain_cases, +}; + +kunit_test_suite(dma_fence_chain_test_suite);
Nothing uses this framework anymore, remove it.
Signed-off-by: Jason Gunthorpe jgg@nvidia.com --- drivers/dma-buf/Kconfig | 5 - drivers/dma-buf/Makefile | 5 - drivers/dma-buf/selftest.c | 167 ----------------------------- drivers/dma-buf/selftest.h | 30 ------ drivers/dma-buf/selftests.h | 12 --- drivers/gpu/drm/i915/Kconfig.debug | 2 +- 6 files changed, 1 insertion(+), 220 deletions(-) delete mode 100644 drivers/dma-buf/selftest.c delete mode 100644 drivers/dma-buf/selftest.h delete mode 100644 drivers/dma-buf/selftests.h
diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index 7d13c8f4484dd3..7efc0f0d07126c 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -49,11 +49,6 @@ config DMABUF_DEBUG exporters. Specifically it validates that importers do not peek at the underlying struct page when they import a buffer.
-config DMABUF_SELFTESTS - tristate "Selftests for the dma-buf interfaces" - default n - depends on DMA_SHARED_BUFFER - config DMABUF_KUNIT_TEST tristate "KUnit tests for DMA-BUF" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index c97ab2d01a7e68..b25d7550bacfd5 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -7,11 +7,6 @@ obj-$(CONFIG_SYNC_FILE) += sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o obj-$(CONFIG_UDMABUF) += udmabuf.o
-dmabuf_selftests-y := \ - selftest.o - -obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o - dmabuf_kunit-y := \ st-dma-fence.o \ st-dma-fence-chain.o \ diff --git a/drivers/dma-buf/selftest.c b/drivers/dma-buf/selftest.c deleted file mode 100644 index c60b6944b4bd18..00000000000000 --- a/drivers/dma-buf/selftest.c +++ /dev/null @@ -1,167 +0,0 @@ -/* SPDX-License-Identifier: MIT */ - -/* - * Copyright © 2019 Intel Corporation - */ - -#include <linux/compiler.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched/signal.h> -#include <linux/slab.h> - -#include "selftest.h" - -enum { -#define selftest(n, func) __idx_##n, -#include "selftests.h" -#undef selftest -}; - -#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f }, -static struct selftest { - bool enabled; - const char *name; - int (*func)(void); -} selftests[] = { -#include "selftests.h" -}; -#undef selftest - -/* Embed the line number into the parameter name so that we can order tests */ -#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n)) -#define selftest_0(n, func, id) \ -module_param_named(id, selftests[__idx_##n].enabled, bool, 0400); -#define selftest(n, func) selftest_0(n, func, param(n)) -#include "selftests.h" -#undef selftest - -int __sanitycheck__(void) -{ - pr_debug("Hello World!\n"); - return 0; -} - -static char *__st_filter; - -static bool apply_subtest_filter(const char *caller, const char *name) -{ - char *filter, *sep, *tok; - bool result = true; - - filter = kstrdup(__st_filter, GFP_KERNEL); - for (sep = filter; (tok = strsep(&sep, ","));) { - bool allow = true; - char *sl; - - if (*tok == '!') { - allow = false; - tok++; - } - - if (*tok == '\0') - continue; - - sl = strchr(tok, '/'); - if (sl) { - *sl++ = '\0'; - if (strcmp(tok, caller)) { - if (allow) - result = false; - continue; - } - tok = sl; - } - - if (strcmp(tok, name)) { - if (allow) - result = false; - continue; - } - - result = allow; - break; - } - kfree(filter); - - return result; -} - -int -__subtests(const char *caller, const struct subtest *st, int count, void *data) -{ - int err; - - for (; count--; st++) { - cond_resched(); - if (signal_pending(current)) - return -EINTR; - - if (!apply_subtest_filter(caller, st->name)) - continue; - - pr_info("dma-buf: Running %s/%s\n", caller, st->name); - - err = st->func(data); - if (err && err != -EINTR) { - pr_err("dma-buf/%s: %s failed with error %d\n", - caller, st->name, err); - return err; - } - } - - return 0; -} - -static void set_default_test_all(struct selftest *st, unsigned long count) -{ - unsigned long i; - - for (i = 0; i < count; i++) - if (st[i].enabled) - return; - - for (i = 0; i < count; i++) - st[i].enabled = true; -} - -static int run_selftests(struct selftest *st, unsigned long count) -{ - int err = 0; - - set_default_test_all(st, count); - - /* Tests are listed in natural order in selftests.h */ - for (; count--; st++) { - if (!st->enabled) - continue; - - pr_info("dma-buf: Running %s\n", st->name); - err = st->func(); - if (err) - break; - } - - if (WARN(err > 0 || err == -ENOTTY, - "%s returned %d, conflicting with selftest's magic values!\n", - st->name, err)) - err = -1; - - return err; -} - -static int __init st_init(void) -{ - return run_selftests(selftests, ARRAY_SIZE(selftests)); -} - -static void __exit st_exit(void) -{ -} - -module_param_named(st_filter, __st_filter, charp, 0400); -module_init(st_init); -module_exit(st_exit); - -MODULE_DESCRIPTION("Self-test harness for dma-buf"); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/dma-buf/selftest.h b/drivers/dma-buf/selftest.h deleted file mode 100644 index 45793aff61425a..00000000000000 --- a/drivers/dma-buf/selftest.h +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: MIT - -/* - * Copyright © 2019 Intel Corporation - */ - -#ifndef __SELFTEST_H__ -#define __SELFTEST_H__ - -#include <linux/compiler.h> - -#define selftest(name, func) int func(void); -#include "selftests.h" -#undef selftest - -struct subtest { - int (*func)(void *data); - const char *name; -}; - -int __subtests(const char *caller, - const struct subtest *st, - int count, - void *data); -#define subtests(T, data) \ - __subtests(__func__, T, ARRAY_SIZE(T), data) - -#define SUBTEST(x) { x, #x } - -#endif /* __SELFTEST_H__ */ diff --git a/drivers/dma-buf/selftests.h b/drivers/dma-buf/selftests.h deleted file mode 100644 index 37b7251841278e..00000000000000 --- a/drivers/dma-buf/selftests.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* List each unit test as selftest(name, function) - * - * The name is used as both an enum and expanded as subtest__name to create - * a module parameter. It must be unique and legal for a C identifier. - * - * The function should be of type int function(void). It may be conditionally - * compiled using #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST). - * - * Tests are executed in order by igt/dmabuf_selftest - */ -selftest(sanitycheck, __sanitycheck__) /* keep first (igt selfcheck) */ diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index 3562a02ef7adca..52a3a59b4ba2c3 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -51,7 +51,7 @@ config DRM_I915_DEBUG select DRM_DEBUG_MM if DRM=y select DRM_EXPORT_FOR_TESTS if m select DRM_KUNIT_TEST if KUNIT - select DMABUF_SELFTESTS + select DMABUF_KUNIT_TEST if KUNIT select SW_SYNC # signaling validation framework (igt/syncobj*) select DRM_I915_WERROR select DRM_I915_DEBUG_GEM
linaro-mm-sig@lists.linaro.org