hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/gpu/drm/i915/i915_sw_fence.c
....@@ -1,19 +1,22 @@
11 /*
2
- * (C) Copyright 2016 Intel Corporation
2
+ * SPDX-License-Identifier: MIT
33 *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation; version 2
7
- * of the License.
4
+ * (C) Copyright 2016 Intel Corporation
85 */
96
107 #include <linux/slab.h>
118 #include <linux/dma-fence.h>
129 #include <linux/irq_work.h>
13
-#include <linux/reservation.h>
10
+#include <linux/dma-resv.h>
1411
1512 #include "i915_sw_fence.h"
1613 #include "i915_selftest.h"
14
+
15
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
16
+#define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
17
+#else
18
+#define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
19
+#endif
1720
1821 #define I915_SW_FENCE_FLAG_ALLOC BIT(3) /* after WQ_FLAG_* for safety */
1922
....@@ -24,14 +27,14 @@
2427 DEBUG_FENCE_NOTIFY,
2528 };
2629
27
-#ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
28
-
2930 static void *i915_sw_fence_debug_hint(void *addr)
3031 {
3132 return (void *)(((struct i915_sw_fence *)addr)->flags & I915_SW_FENCE_MASK);
3233 }
3334
34
-static struct debug_obj_descr i915_sw_fence_debug_descr = {
35
+#ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
36
+
37
+static const struct debug_obj_descr i915_sw_fence_debug_descr = {
3538 .name = "i915_sw_fence",
3639 .debug_hint = i915_sw_fence_debug_hint,
3740 };
....@@ -160,8 +163,15 @@
160163 LIST_HEAD(extra);
161164
162165 do {
163
- list_for_each_entry_safe(pos, next, &x->head, entry)
164
- pos->func(pos, TASK_NORMAL, 0, &extra);
166
+ list_for_each_entry_safe(pos, next, &x->head, entry) {
167
+ int wake_flags;
168
+
169
+ wake_flags = fence->error;
170
+ if (pos->func == autoremove_wake_function)
171
+ wake_flags = 0;
172
+
173
+ pos->func(pos, TASK_NORMAL, wake_flags, &extra);
174
+ }
165175
166176 if (list_empty(&extra))
167177 break;
....@@ -195,7 +205,7 @@
195205 __i915_sw_fence_notify(fence, FENCE_FREE);
196206 }
197207
198
-static void i915_sw_fence_complete(struct i915_sw_fence *fence)
208
+void i915_sw_fence_complete(struct i915_sw_fence *fence)
199209 {
200210 debug_fence_assert(fence);
201211
....@@ -205,10 +215,21 @@
205215 __i915_sw_fence_complete(fence, NULL);
206216 }
207217
208
-static void i915_sw_fence_await(struct i915_sw_fence *fence)
218
+bool i915_sw_fence_await(struct i915_sw_fence *fence)
209219 {
210
- debug_fence_assert(fence);
211
- WARN_ON(atomic_inc_return(&fence->pending) <= 1);
220
+ int pending;
221
+
222
+ /*
223
+ * It is only safe to add a new await to the fence while it has
224
+ * not yet been signaled (i.e. there are still existing signalers).
225
+ */
226
+ pending = atomic_read(&fence->pending);
227
+ do {
228
+ if (pending < 1)
229
+ return false;
230
+ } while (!atomic_try_cmpxchg(&fence->pending, &pending, pending + 1));
231
+
232
+ return true;
212233 }
213234
214235 void __i915_sw_fence_init(struct i915_sw_fence *fence,
....@@ -218,11 +239,21 @@
218239 {
219240 BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
220241
242
+ __init_waitqueue_head(&fence->wait, name, key);
243
+ fence->flags = (unsigned long)fn;
244
+
245
+ i915_sw_fence_reinit(fence);
246
+}
247
+
248
+void i915_sw_fence_reinit(struct i915_sw_fence *fence)
249
+{
221250 debug_fence_init(fence);
222251
223
- __init_waitqueue_head(&fence->wait, name, key);
224252 atomic_set(&fence->pending, 1);
225
- fence->flags = (unsigned long)fn;
253
+ fence->error = 0;
254
+
255
+ I915_SW_FENCE_BUG_ON(!fence->flags);
256
+ I915_SW_FENCE_BUG_ON(!list_empty(&fence->wait.head));
226257 }
227258
228259 void i915_sw_fence_commit(struct i915_sw_fence *fence)
....@@ -233,6 +264,8 @@
233264
234265 static int i915_sw_fence_wake(wait_queue_entry_t *wq, unsigned mode, int flags, void *key)
235266 {
267
+ i915_sw_fence_set_error_once(wq->private, flags);
268
+
236269 list_del(&wq->entry);
237270 __i915_sw_fence_complete(wq->private, key);
238271
....@@ -305,8 +338,10 @@
305338 debug_fence_assert(fence);
306339 might_sleep_if(gfpflags_allow_blocking(gfp));
307340
308
- if (i915_sw_fence_done(signaler))
341
+ if (i915_sw_fence_done(signaler)) {
342
+ i915_sw_fence_set_error_once(fence, signaler->error);
309343 return 0;
344
+ }
310345
311346 debug_fence_assert(signaler);
312347
....@@ -322,6 +357,7 @@
322357 return -ENOMEM;
323358
324359 i915_sw_fence_wait(signaler);
360
+ i915_sw_fence_set_error_once(fence, signaler->error);
325361 return 0;
326362 }
327363
....@@ -340,7 +376,7 @@
340376 __add_wait_queue_entry_tail(&signaler->wait, wq);
341377 pending = 1;
342378 } else {
343
- i915_sw_fence_wake(wq, 0, 0, NULL);
379
+ i915_sw_fence_wake(wq, 0, signaler->error, NULL);
344380 pending = 0;
345381 }
346382 spin_unlock_irqrestore(&signaler->wait.lock, flags);
....@@ -362,11 +398,6 @@
362398 return __i915_sw_fence_await_sw_fence(fence, signaler, NULL, gfp);
363399 }
364400
365
-struct i915_sw_dma_fence_cb {
366
- struct dma_fence_cb base;
367
- struct i915_sw_fence *fence;
368
-};
369
-
370401 struct i915_sw_dma_fence_cb_timer {
371402 struct i915_sw_dma_fence_cb base;
372403 struct dma_fence *dma;
....@@ -380,6 +411,7 @@
380411 {
381412 struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
382413
414
+ i915_sw_fence_set_error_once(cb->fence, dma->error);
383415 i915_sw_fence_complete(cb->fence);
384416 kfree(cb);
385417 }
....@@ -393,11 +425,13 @@
393425 if (!fence)
394426 return;
395427
396
- pr_warn("asynchronous wait on fence %s:%s:%x timed out\n",
397
- cb->dma->ops->get_driver_name(cb->dma),
398
- cb->dma->ops->get_timeline_name(cb->dma),
399
- cb->dma->seqno);
428
+ pr_notice("Asynchronous wait on fence %s:%s:%llx timed out (hint:%ps)\n",
429
+ cb->dma->ops->get_driver_name(cb->dma),
430
+ cb->dma->ops->get_timeline_name(cb->dma),
431
+ cb->dma->seqno,
432
+ i915_sw_fence_debug_hint(fence));
400433
434
+ i915_sw_fence_set_error_once(fence, -ETIMEDOUT);
401435 i915_sw_fence_complete(fence);
402436 }
403437
....@@ -409,8 +443,10 @@
409443 struct i915_sw_fence *fence;
410444
411445 fence = xchg(&cb->base.fence, NULL);
412
- if (fence)
446
+ if (fence) {
447
+ i915_sw_fence_set_error_once(fence, dma->error);
413448 i915_sw_fence_complete(fence);
449
+ }
414450
415451 irq_work_queue(&cb->work);
416452 }
....@@ -438,8 +474,10 @@
438474 debug_fence_assert(fence);
439475 might_sleep_if(gfpflags_allow_blocking(gfp));
440476
441
- if (dma_fence_is_signaled(dma))
477
+ if (dma_fence_is_signaled(dma)) {
478
+ i915_sw_fence_set_error_once(fence, dma->error);
442479 return 0;
480
+ }
443481
444482 cb = kmalloc(timeout ?
445483 sizeof(struct i915_sw_dma_fence_cb_timer) :
....@@ -449,7 +487,12 @@
449487 if (!gfpflags_allow_blocking(gfp))
450488 return -ENOMEM;
451489
452
- return dma_fence_wait(dma, false);
490
+ ret = dma_fence_wait(dma, false);
491
+ if (ret)
492
+ return ret;
493
+
494
+ i915_sw_fence_set_error_once(fence, dma->error);
495
+ return 0;
453496 }
454497
455498 cb->fence = fence;
....@@ -482,8 +525,43 @@
482525 return ret;
483526 }
484527
528
+static void __dma_i915_sw_fence_wake(struct dma_fence *dma,
529
+ struct dma_fence_cb *data)
530
+{
531
+ struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
532
+
533
+ i915_sw_fence_set_error_once(cb->fence, dma->error);
534
+ i915_sw_fence_complete(cb->fence);
535
+}
536
+
537
+int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
538
+ struct dma_fence *dma,
539
+ struct i915_sw_dma_fence_cb *cb)
540
+{
541
+ int ret;
542
+
543
+ debug_fence_assert(fence);
544
+
545
+ if (dma_fence_is_signaled(dma)) {
546
+ i915_sw_fence_set_error_once(fence, dma->error);
547
+ return 0;
548
+ }
549
+
550
+ cb->fence = fence;
551
+ i915_sw_fence_await(fence);
552
+
553
+ ret = 1;
554
+ if (dma_fence_add_callback(dma, &cb->base, __dma_i915_sw_fence_wake)) {
555
+ /* fence already signaled */
556
+ __dma_i915_sw_fence_wake(dma, &cb->base);
557
+ ret = 0;
558
+ }
559
+
560
+ return ret;
561
+}
562
+
485563 int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
486
- struct reservation_object *resv,
564
+ struct dma_resv *resv,
487565 const struct dma_fence_ops *exclude,
488566 bool write,
489567 unsigned long timeout,
....@@ -499,8 +577,7 @@
499577 struct dma_fence **shared;
500578 unsigned int count, i;
501579
502
- ret = reservation_object_get_fences_rcu(resv,
503
- &excl, &count, &shared);
580
+ ret = dma_resv_get_fences_rcu(resv, &excl, &count, &shared);
504581 if (ret)
505582 return ret;
506583
....@@ -524,7 +601,7 @@
524601 dma_fence_put(shared[i]);
525602 kfree(shared);
526603 } else {
527
- excl = reservation_object_get_excl_rcu(resv);
604
+ excl = dma_resv_get_excl_rcu(resv);
528605 }
529606
530607 if (ret >= 0 && excl && excl->ops != exclude) {