1 // SPDX-License-Identifier: MIT
4 * Copyright (C) 2022 Advanced Micro Devices, Inc.
7 #include <linux/dma-fence-unwrap.h>
9 #include <linux/kernel.h>
10 #include <linux/kthread.h>
12 #include <linux/sched/signal.h>
13 #include <linux/slab.h>
14 #include <linux/spinlock.h>
15 #include <linux/random.h>
20 #define CHAIN_SZ (4 << 10)
22 static inline struct mock_fence {
23 struct dma_fence base;
25 } *to_mock_fence(struct dma_fence *f) {
26 return container_of(f, struct mock_fence, base);
29 static const char *mock_name(struct dma_fence *f)
34 static const struct dma_fence_ops mock_ops = {
35 .get_driver_name = mock_name,
36 .get_timeline_name = mock_name,
39 static struct dma_fence *mock_fence(void)
43 f = kmalloc(sizeof(*f), GFP_KERNEL);
47 spin_lock_init(&f->lock);
48 dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
53 static struct dma_fence *mock_array(unsigned int num_fences, ...)
55 struct dma_fence_array *array;
56 struct dma_fence **fences;
60 fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
64 va_start(valist, num_fences);
65 for (i = 0; i < num_fences; ++i)
66 fences[i] = va_arg(valist, typeof(*fences));
69 array = dma_fence_array_create(num_fences, fences,
70 dma_fence_context_alloc(1),
77 for (i = 0; i < num_fences; ++i)
78 dma_fence_put(fences[i]);
83 static struct dma_fence *mock_chain(struct dma_fence *prev,
84 struct dma_fence *fence)
86 struct dma_fence_chain *f;
88 f = dma_fence_chain_alloc();
95 dma_fence_chain_init(f, prev, fence, 1);
99 static int sanitycheck(void *arg)
101 struct dma_fence *f, *chain, *array;
108 array = mock_array(1, f);
112 chain = mock_chain(NULL, array);
117 dma_fence_put(chain);
121 static int unwrap_array(void *arg)
123 struct dma_fence *fence, *f1, *f2, *array;
124 struct dma_fence_unwrap iter;
137 array = mock_array(2, f1, f2);
141 dma_fence_unwrap_for_each(fence, &iter, array) {
144 } else if (fence == f2) {
147 pr_err("Unexpected fence!\n");
153 pr_err("Not all fences seen!\n");
157 dma_fence_signal(f1);
158 dma_fence_signal(f2);
159 dma_fence_put(array);
163 static int unwrap_chain(void *arg)
165 struct dma_fence *fence, *f1, *f2, *chain;
166 struct dma_fence_unwrap iter;
179 chain = mock_chain(f1, f2);
183 dma_fence_unwrap_for_each(fence, &iter, chain) {
186 } else if (fence == f2) {
189 pr_err("Unexpected fence!\n");
195 pr_err("Not all fences seen!\n");
199 dma_fence_signal(f1);
200 dma_fence_signal(f2);
201 dma_fence_put(chain);
205 static int unwrap_chain_array(void *arg)
207 struct dma_fence *fence, *f1, *f2, *array, *chain;
208 struct dma_fence_unwrap iter;
221 array = mock_array(2, f1, f2);
225 chain = mock_chain(NULL, array);
229 dma_fence_unwrap_for_each(fence, &iter, chain) {
232 } else if (fence == f2) {
235 pr_err("Unexpected fence!\n");
241 pr_err("Not all fences seen!\n");
245 dma_fence_signal(f1);
246 dma_fence_signal(f2);
247 dma_fence_put(chain);
251 int dma_fence_unwrap(void)
253 static const struct subtest tests[] = {
254 SUBTEST(sanitycheck),
255 SUBTEST(unwrap_array),
256 SUBTEST(unwrap_chain),
257 SUBTEST(unwrap_chain_array),
260 return subtests(tests, NULL);