LoongArch: Parse MADT to get multi-processor information
[linux-2.6-microblaze.git] / drivers / dma-buf / st-dma-fence-unwrap.c
1 // SPDX-License-Identifier: MIT
2
3 /*
4  * Copyright (C) 2022 Advanced Micro Devices, Inc.
5  */
6
7 #include <linux/dma-fence-unwrap.h>
8 #if 0
9 #include <linux/kernel.h>
10 #include <linux/kthread.h>
11 #include <linux/mm.h>
12 #include <linux/sched/signal.h>
13 #include <linux/slab.h>
14 #include <linux/spinlock.h>
15 #include <linux/random.h>
16 #endif
17
18 #include "selftest.h"
19
20 #define CHAIN_SZ (4 << 10)
21
22 static inline struct mock_fence {
23         struct dma_fence base;
24         spinlock_t lock;
25 } *to_mock_fence(struct dma_fence *f) {
26         return container_of(f, struct mock_fence, base);
27 }
28
29 static const char *mock_name(struct dma_fence *f)
30 {
31         return "mock";
32 }
33
34 static const struct dma_fence_ops mock_ops = {
35         .get_driver_name = mock_name,
36         .get_timeline_name = mock_name,
37 };
38
39 static struct dma_fence *mock_fence(void)
40 {
41         struct mock_fence *f;
42
43         f = kmalloc(sizeof(*f), GFP_KERNEL);
44         if (!f)
45                 return NULL;
46
47         spin_lock_init(&f->lock);
48         dma_fence_init(&f->base, &mock_ops, &f->lock, 0, 0);
49
50         return &f->base;
51 }
52
53 static struct dma_fence *mock_array(unsigned int num_fences, ...)
54 {
55         struct dma_fence_array *array;
56         struct dma_fence **fences;
57         va_list valist;
58         int i;
59
60         fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL);
61         if (!fences)
62                 return NULL;
63
64         va_start(valist, num_fences);
65         for (i = 0; i < num_fences; ++i)
66                 fences[i] = va_arg(valist, typeof(*fences));
67         va_end(valist);
68
69         array = dma_fence_array_create(num_fences, fences,
70                                        dma_fence_context_alloc(1),
71                                        1, false);
72         if (!array)
73                 goto cleanup;
74         return &array->base;
75
76 cleanup:
77         for (i = 0; i < num_fences; ++i)
78                 dma_fence_put(fences[i]);
79         kfree(fences);
80         return NULL;
81 }
82
83 static struct dma_fence *mock_chain(struct dma_fence *prev,
84                                     struct dma_fence *fence)
85 {
86         struct dma_fence_chain *f;
87
88         f = dma_fence_chain_alloc();
89         if (!f) {
90                 dma_fence_put(prev);
91                 dma_fence_put(fence);
92                 return NULL;
93         }
94
95         dma_fence_chain_init(f, prev, fence, 1);
96         return &f->base;
97 }
98
99 static int sanitycheck(void *arg)
100 {
101         struct dma_fence *f, *chain, *array;
102         int err = 0;
103
104         f = mock_fence();
105         if (!f)
106                 return -ENOMEM;
107
108         array = mock_array(1, f);
109         if (!array)
110                 return -ENOMEM;
111
112         chain = mock_chain(NULL, array);
113         if (!chain)
114                 return -ENOMEM;
115
116         dma_fence_signal(f);
117         dma_fence_put(chain);
118         return err;
119 }
120
121 static int unwrap_array(void *arg)
122 {
123         struct dma_fence *fence, *f1, *f2, *array;
124         struct dma_fence_unwrap iter;
125         int err = 0;
126
127         f1 = mock_fence();
128         if (!f1)
129                 return -ENOMEM;
130
131         f2 = mock_fence();
132         if (!f2) {
133                 dma_fence_put(f1);
134                 return -ENOMEM;
135         }
136
137         array = mock_array(2, f1, f2);
138         if (!array)
139                 return -ENOMEM;
140
141         dma_fence_unwrap_for_each(fence, &iter, array) {
142                 if (fence == f1) {
143                         f1 = NULL;
144                 } else if (fence == f2) {
145                         f2 = NULL;
146                 } else {
147                         pr_err("Unexpected fence!\n");
148                         err = -EINVAL;
149                 }
150         }
151
152         if (f1 || f2) {
153                 pr_err("Not all fences seen!\n");
154                 err = -EINVAL;
155         }
156
157         dma_fence_signal(f1);
158         dma_fence_signal(f2);
159         dma_fence_put(array);
160         return 0;
161 }
162
163 static int unwrap_chain(void *arg)
164 {
165         struct dma_fence *fence, *f1, *f2, *chain;
166         struct dma_fence_unwrap iter;
167         int err = 0;
168
169         f1 = mock_fence();
170         if (!f1)
171                 return -ENOMEM;
172
173         f2 = mock_fence();
174         if (!f2) {
175                 dma_fence_put(f1);
176                 return -ENOMEM;
177         }
178
179         chain = mock_chain(f1, f2);
180         if (!chain)
181                 return -ENOMEM;
182
183         dma_fence_unwrap_for_each(fence, &iter, chain) {
184                 if (fence == f1) {
185                         f1 = NULL;
186                 } else if (fence == f2) {
187                         f2 = NULL;
188                 } else {
189                         pr_err("Unexpected fence!\n");
190                         err = -EINVAL;
191                 }
192         }
193
194         if (f1 || f2) {
195                 pr_err("Not all fences seen!\n");
196                 err = -EINVAL;
197         }
198
199         dma_fence_signal(f1);
200         dma_fence_signal(f2);
201         dma_fence_put(chain);
202         return 0;
203 }
204
205 static int unwrap_chain_array(void *arg)
206 {
207         struct dma_fence *fence, *f1, *f2, *array, *chain;
208         struct dma_fence_unwrap iter;
209         int err = 0;
210
211         f1 = mock_fence();
212         if (!f1)
213                 return -ENOMEM;
214
215         f2 = mock_fence();
216         if (!f2) {
217                 dma_fence_put(f1);
218                 return -ENOMEM;
219         }
220
221         array = mock_array(2, f1, f2);
222         if (!array)
223                 return -ENOMEM;
224
225         chain = mock_chain(NULL, array);
226         if (!chain)
227                 return -ENOMEM;
228
229         dma_fence_unwrap_for_each(fence, &iter, chain) {
230                 if (fence == f1) {
231                         f1 = NULL;
232                 } else if (fence == f2) {
233                         f2 = NULL;
234                 } else {
235                         pr_err("Unexpected fence!\n");
236                         err = -EINVAL;
237                 }
238         }
239
240         if (f1 || f2) {
241                 pr_err("Not all fences seen!\n");
242                 err = -EINVAL;
243         }
244
245         dma_fence_signal(f1);
246         dma_fence_signal(f2);
247         dma_fence_put(chain);
248         return 0;
249 }
250
251 int dma_fence_unwrap(void)
252 {
253         static const struct subtest tests[] = {
254                 SUBTEST(sanitycheck),
255                 SUBTEST(unwrap_array),
256                 SUBTEST(unwrap_chain),
257                 SUBTEST(unwrap_chain_array),
258         };
259
260         return subtests(tests, NULL);
261 }