summaryrefslogtreecommitdiffstats
path: root/drivers/dma-buf/selftest.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-08-19 05:59:26 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2019-08-19 13:01:34 -0400
commit9536b64ac0d6e3151963a11441dde7ade045fb29 (patch)
treefa992f4f91d0b5052157727c9ef5ebe0e4c356e0 /drivers/dma-buf/selftest.c
parentaa4fffec310da5eb6d6ef09509b03e780bdf248a (diff)
dma-buf: Introduce selftesting framework
In light of recent review slip ups, the absence of a suite of tests for dma-buf became apparent. Given the current plethora of testing frameworks, opt for one already in use by Intel's CI and so allow easy hook up into igt. We introduce a new module that when loaded will execute the list of selftests and their subtest. The names of the selftests are put into the modinfo as parameters so that igt can identify each, and run them independently, principally for ease of error reporting. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Tomi Sarvela <tomi.p.sarvela@intel.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: https://patchwork.freedesktop.org/patch/msgid/20190819095928.32091-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/dma-buf/selftest.c')
-rw-r--r--drivers/dma-buf/selftest.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/drivers/dma-buf/selftest.c b/drivers/dma-buf/selftest.c
new file mode 100644
index 000000000000..c60b6944b4bd
--- /dev/null
+++ b/drivers/dma-buf/selftest.c
@@ -0,0 +1,167 @@
1/* SPDX-License-Identifier: MIT */
2
3/*
4 * Copyright © 2019 Intel Corporation
5 */
6
7#include <linux/compiler.h>
8#include <linux/kernel.h>
9#include <linux/module.h>
10#include <linux/sched/signal.h>
11#include <linux/slab.h>
12
13#include "selftest.h"
14
15enum {
16#define selftest(n, func) __idx_##n,
17#include "selftests.h"
18#undef selftest
19};
20
21#define selftest(n, f) [__idx_##n] = { .name = #n, .func = f },
22static struct selftest {
23 bool enabled;
24 const char *name;
25 int (*func)(void);
26} selftests[] = {
27#include "selftests.h"
28};
29#undef selftest
30
31/* Embed the line number into the parameter name so that we can order tests */
32#define param(n) __PASTE(igt__, __PASTE(__PASTE(__LINE__, __), n))
33#define selftest_0(n, func, id) \
34module_param_named(id, selftests[__idx_##n].enabled, bool, 0400);
35#define selftest(n, func) selftest_0(n, func, param(n))
36#include "selftests.h"
37#undef selftest
38
39int __sanitycheck__(void)
40{
41 pr_debug("Hello World!\n");
42 return 0;
43}
44
45static char *__st_filter;
46
47static bool apply_subtest_filter(const char *caller, const char *name)
48{
49 char *filter, *sep, *tok;
50 bool result = true;
51
52 filter = kstrdup(__st_filter, GFP_KERNEL);
53 for (sep = filter; (tok = strsep(&sep, ","));) {
54 bool allow = true;
55 char *sl;
56
57 if (*tok == '!') {
58 allow = false;
59 tok++;
60 }
61
62 if (*tok == '\0')
63 continue;
64
65 sl = strchr(tok, '/');
66 if (sl) {
67 *sl++ = '\0';
68 if (strcmp(tok, caller)) {
69 if (allow)
70 result = false;
71 continue;
72 }
73 tok = sl;
74 }
75
76 if (strcmp(tok, name)) {
77 if (allow)
78 result = false;
79 continue;
80 }
81
82 result = allow;
83 break;
84 }
85 kfree(filter);
86
87 return result;
88}
89
90int
91__subtests(const char *caller, const struct subtest *st, int count, void *data)
92{
93 int err;
94
95 for (; count--; st++) {
96 cond_resched();
97 if (signal_pending(current))
98 return -EINTR;
99
100 if (!apply_subtest_filter(caller, st->name))
101 continue;
102
103 pr_info("dma-buf: Running %s/%s\n", caller, st->name);
104
105 err = st->func(data);
106 if (err && err != -EINTR) {
107 pr_err("dma-buf/%s: %s failed with error %d\n",
108 caller, st->name, err);
109 return err;
110 }
111 }
112
113 return 0;
114}
115
116static void set_default_test_all(struct selftest *st, unsigned long count)
117{
118 unsigned long i;
119
120 for (i = 0; i < count; i++)
121 if (st[i].enabled)
122 return;
123
124 for (i = 0; i < count; i++)
125 st[i].enabled = true;
126}
127
128static int run_selftests(struct selftest *st, unsigned long count)
129{
130 int err = 0;
131
132 set_default_test_all(st, count);
133
134 /* Tests are listed in natural order in selftests.h */
135 for (; count--; st++) {
136 if (!st->enabled)
137 continue;
138
139 pr_info("dma-buf: Running %s\n", st->name);
140 err = st->func();
141 if (err)
142 break;
143 }
144
145 if (WARN(err > 0 || err == -ENOTTY,
146 "%s returned %d, conflicting with selftest's magic values!\n",
147 st->name, err))
148 err = -1;
149
150 return err;
151}
152
153static int __init st_init(void)
154{
155 return run_selftests(selftests, ARRAY_SIZE(selftests));
156}
157
158static void __exit st_exit(void)
159{
160}
161
162module_param_named(st_filter, __st_filter, charp, 0400);
163module_init(st_init);
164module_exit(st_exit);
165
166MODULE_DESCRIPTION("Self-test harness for dma-buf");
167MODULE_LICENSE("GPL and additional rights");