2 * Copyright © 2017 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 #include <linux/completion.h>
26 #include <linux/delay.h>
28 #include "../i915_selftest.h"
30 static int __i915_sw_fence_call
31 fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
38 /* Leave the fence for the caller to free it after testing */
45 static struct i915_sw_fence *alloc_fence(void)
47 struct i915_sw_fence *fence;
49 fence = kmalloc(sizeof(*fence), GFP_KERNEL);
53 i915_sw_fence_init(fence, fence_notify);
57 static void free_fence(struct i915_sw_fence *fence)
59 i915_sw_fence_fini(fence);
63 static int __test_self(struct i915_sw_fence *fence)
65 if (i915_sw_fence_done(fence))
68 i915_sw_fence_commit(fence);
69 if (!i915_sw_fence_done(fence))
72 i915_sw_fence_wait(fence);
73 if (!i915_sw_fence_done(fence))
79 static int test_self(void *arg)
81 struct i915_sw_fence *fence;
84 /* Test i915_sw_fence signaling and completion testing */
85 fence = alloc_fence();
89 ret = __test_self(fence);
95 static int test_dag(void *arg)
97 struct i915_sw_fence *A, *B, *C;
100 /* Test detection of cycles within the i915_sw_fence graphs */
101 if (!IS_ENABLED(CONFIG_DRM_I915_SW_FENCE_CHECK_DAG))
108 if (i915_sw_fence_await_sw_fence_gfp(A, A, GFP_KERNEL) != -EINVAL) {
109 pr_err("recursive cycle not detected (AA)\n");
119 i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
120 if (i915_sw_fence_await_sw_fence_gfp(B, A, GFP_KERNEL) != -EINVAL) {
121 pr_err("single depth cycle not detected (BAB)\n");
131 if (i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL) == -EINVAL) {
132 pr_err("invalid cycle detected\n");
135 if (i915_sw_fence_await_sw_fence_gfp(C, B, GFP_KERNEL) != -EINVAL) {
136 pr_err("single depth cycle not detected (CBC)\n");
139 if (i915_sw_fence_await_sw_fence_gfp(C, A, GFP_KERNEL) != -EINVAL) {
140 pr_err("cycle not detected (BA, CB, AC)\n");
143 if (i915_sw_fence_await_sw_fence_gfp(A, C, GFP_KERNEL) == -EINVAL) {
144 pr_err("invalid cycle detected\n");
148 i915_sw_fence_commit(A);
149 i915_sw_fence_commit(B);
150 i915_sw_fence_commit(C);
153 if (!i915_sw_fence_done(C)) {
154 pr_err("fence C not done\n");
157 if (!i915_sw_fence_done(B)) {
158 pr_err("fence B not done\n");
161 if (!i915_sw_fence_done(A)) {
162 pr_err("fence A not done\n");
174 static int test_AB(void *arg)
176 struct i915_sw_fence *A, *B;
179 /* Test i915_sw_fence (A) waiting on an event source (B) */
189 ret = i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
193 pr_err("Incorrectly reported fence A was complete before await\n");
199 i915_sw_fence_commit(A);
200 if (i915_sw_fence_done(A))
203 i915_sw_fence_commit(B);
204 if (!i915_sw_fence_done(B)) {
205 pr_err("Fence B is not done\n");
209 if (!i915_sw_fence_done(A)) {
210 pr_err("Fence A is not done\n");
222 static int test_ABC(void *arg)
224 struct i915_sw_fence *A, *B, *C;
227 /* Test a chain of fences, A waits on B who waits on C */
244 ret = i915_sw_fence_await_sw_fence_gfp(A, B, GFP_KERNEL);
248 pr_err("Incorrectly reported fence B was complete before await\n");
252 ret = i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL);
256 pr_err("Incorrectly reported fence C was complete before await\n");
261 i915_sw_fence_commit(A);
262 if (i915_sw_fence_done(A)) {
263 pr_err("Fence A completed early\n");
267 i915_sw_fence_commit(B);
268 if (i915_sw_fence_done(B)) {
269 pr_err("Fence B completed early\n");
273 if (i915_sw_fence_done(A)) {
274 pr_err("Fence A completed early (after signaling B)\n");
278 i915_sw_fence_commit(C);
281 if (!i915_sw_fence_done(C)) {
282 pr_err("Fence C not done\n");
285 if (!i915_sw_fence_done(B)) {
286 pr_err("Fence B not done\n");
289 if (!i915_sw_fence_done(A)) {
290 pr_err("Fence A not done\n");
302 static int test_AB_C(void *arg)
304 struct i915_sw_fence *A, *B, *C;
307 /* Test multiple fences (AB) waiting on a single event (C) */
324 ret = i915_sw_fence_await_sw_fence_gfp(A, C, GFP_KERNEL);
332 ret = i915_sw_fence_await_sw_fence_gfp(B, C, GFP_KERNEL);
340 i915_sw_fence_commit(A);
341 i915_sw_fence_commit(B);
344 if (i915_sw_fence_done(A)) {
345 pr_err("Fence A completed early\n");
349 if (i915_sw_fence_done(B)) {
350 pr_err("Fence B completed early\n");
354 i915_sw_fence_commit(C);
355 if (!i915_sw_fence_done(C)) {
356 pr_err("Fence C not done\n");
360 if (!i915_sw_fence_done(B)) {
361 pr_err("Fence B not done\n");
365 if (!i915_sw_fence_done(A)) {
366 pr_err("Fence A not done\n");
379 static int test_C_AB(void *arg)
381 struct i915_sw_fence *A, *B, *C;
384 /* Test multiple event sources (A,B) for a single fence (C) */
401 ret = i915_sw_fence_await_sw_fence_gfp(C, A, GFP_KERNEL);
409 ret = i915_sw_fence_await_sw_fence_gfp(C, B, GFP_KERNEL);
418 i915_sw_fence_commit(C);
419 if (i915_sw_fence_done(C))
422 i915_sw_fence_commit(A);
423 i915_sw_fence_commit(B);
425 if (!i915_sw_fence_done(A)) {
426 pr_err("Fence A not done\n");
430 if (!i915_sw_fence_done(B)) {
431 pr_err("Fence B not done\n");
435 if (!i915_sw_fence_done(C)) {
436 pr_err("Fence C not done\n");
449 static int test_chain(void *arg)
452 struct i915_sw_fence **fences;
455 /* Test a long chain of fences */
456 fences = kmalloc_array(nfences, sizeof(*fences), GFP_KERNEL);
460 for (i = 0; i < nfences; i++) {
461 fences[i] = alloc_fence();
469 ret = i915_sw_fence_await_sw_fence_gfp(fences[i],
477 i915_sw_fence_commit(fences[i]);
482 for (i = nfences; --i; ) {
483 if (i915_sw_fence_done(fences[i])) {
485 pr_err("Fence[%d] completed early\n", i);
489 i915_sw_fence_commit(fences[0]);
490 for (i = 0; ret == 0 && i < nfences; i++) {
491 if (!i915_sw_fence_done(fences[i])) {
492 pr_err("Fence[%d] is not done\n", i);
498 for (i = 0; i < nfences; i++)
499 free_fence(fences[i]);
505 struct work_struct work;
506 struct completion started;
507 struct i915_sw_fence *in, *out;
511 static void task_ipc(struct work_struct *work)
513 struct task_ipc *ipc = container_of(work, typeof(*ipc), work);
515 complete(&ipc->started);
517 i915_sw_fence_wait(ipc->in);
518 smp_store_mb(ipc->value, 1);
519 i915_sw_fence_commit(ipc->out);
522 static int test_ipc(void *arg)
527 /* Test use of i915_sw_fence as an interprocess signaling mechanism */
528 ipc.in = alloc_fence();
531 ipc.out = alloc_fence();
537 /* use a completion to avoid chicken-and-egg testing */
538 init_completion(&ipc.started);
541 INIT_WORK_ONSTACK(&ipc.work, task_ipc);
542 schedule_work(&ipc.work);
544 wait_for_completion(&ipc.started);
546 usleep_range(1000, 2000);
547 if (READ_ONCE(ipc.value)) {
548 pr_err("worker updated value before i915_sw_fence was signaled\n");
552 i915_sw_fence_commit(ipc.in);
553 i915_sw_fence_wait(ipc.out);
555 if (!READ_ONCE(ipc.value)) {
556 pr_err("worker signaled i915_sw_fence before value was posted\n");
560 flush_work(&ipc.work);
561 destroy_work_on_stack(&ipc.work);
568 int i915_sw_fence_mock_selftests(void)
570 static const struct i915_subtest tests[] = {
581 return i915_subtests(tests, NULL);