Home | History | Annotate | Line # | Download | only in i915
      1  1.6  riastrad /*	$NetBSD: i915_sw_fence.c,v 1.6 2021/12/19 12:11:46 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * SPDX-License-Identifier: MIT
      5  1.1  riastrad  *
      6  1.1  riastrad  * (C) Copyright 2016 Intel Corporation
      7  1.1  riastrad  */
      8  1.1  riastrad 
      9  1.1  riastrad #include <sys/cdefs.h>
     10  1.6  riastrad __KERNEL_RCSID(0, "$NetBSD: i915_sw_fence.c,v 1.6 2021/12/19 12:11:46 riastradh Exp $");
     11  1.1  riastrad 
     12  1.1  riastrad #include <linux/slab.h>
     13  1.1  riastrad #include <linux/dma-fence.h>
     14  1.1  riastrad #include <linux/irq_work.h>
     15  1.1  riastrad #include <linux/dma-resv.h>
     16  1.1  riastrad 
     17  1.1  riastrad #include "i915_sw_fence.h"
     18  1.1  riastrad #include "i915_selftest.h"
     19  1.1  riastrad 
     20  1.3  riastrad #include <drm/drm_wait_netbsd.h>
     21  1.3  riastrad 
     22  1.3  riastrad #include <linux/nbsd-namespace.h>
     23  1.3  riastrad 
     24  1.1  riastrad #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
     25  1.1  riastrad #define I915_SW_FENCE_BUG_ON(expr) BUG_ON(expr)
     26  1.1  riastrad #else
     27  1.1  riastrad #define I915_SW_FENCE_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr)
     28  1.1  riastrad #endif
     29  1.1  riastrad 
     30  1.1  riastrad #define I915_SW_FENCE_FLAG_ALLOC BIT(3) /* after WQ_FLAG_* for safety */
     31  1.1  riastrad 
     32  1.3  riastrad #ifdef __NetBSD__		/* XXX */
     33  1.3  riastrad spinlock_t i915_sw_fence_lock;
     34  1.3  riastrad #else
     35  1.1  riastrad static DEFINE_SPINLOCK(i915_sw_fence_lock);
     36  1.3  riastrad #endif
     37  1.1  riastrad 
     38  1.1  riastrad enum {
     39  1.1  riastrad 	DEBUG_FENCE_IDLE = 0,
     40  1.1  riastrad 	DEBUG_FENCE_NOTIFY,
     41  1.1  riastrad };
     42  1.1  riastrad 
     43  1.1  riastrad static void *i915_sw_fence_debug_hint(void *addr)
     44  1.1  riastrad {
     45  1.1  riastrad 	return (void *)(((struct i915_sw_fence *)addr)->flags & I915_SW_FENCE_MASK);
     46  1.1  riastrad }
     47  1.1  riastrad 
     48  1.1  riastrad #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
     49  1.1  riastrad 
     50  1.1  riastrad static struct debug_obj_descr i915_sw_fence_debug_descr = {
     51  1.1  riastrad 	.name = "i915_sw_fence",
     52  1.1  riastrad 	.debug_hint = i915_sw_fence_debug_hint,
     53  1.1  riastrad };
     54  1.1  riastrad 
     55  1.1  riastrad static inline void debug_fence_init(struct i915_sw_fence *fence)
     56  1.1  riastrad {
     57  1.1  riastrad 	debug_object_init(fence, &i915_sw_fence_debug_descr);
     58  1.1  riastrad }
     59  1.1  riastrad 
     60  1.1  riastrad static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
     61  1.1  riastrad {
     62  1.1  riastrad 	debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr);
     63  1.1  riastrad }
     64  1.1  riastrad 
     65  1.1  riastrad static inline void debug_fence_activate(struct i915_sw_fence *fence)
     66  1.1  riastrad {
     67  1.1  riastrad 	debug_object_activate(fence, &i915_sw_fence_debug_descr);
     68  1.1  riastrad }
     69  1.1  riastrad 
     70  1.1  riastrad static inline void debug_fence_set_state(struct i915_sw_fence *fence,
     71  1.1  riastrad 					 int old, int new)
     72  1.1  riastrad {
     73  1.1  riastrad 	debug_object_active_state(fence, &i915_sw_fence_debug_descr, old, new);
     74  1.1  riastrad }
     75  1.1  riastrad 
     76  1.1  riastrad static inline void debug_fence_deactivate(struct i915_sw_fence *fence)
     77  1.1  riastrad {
     78  1.1  riastrad 	debug_object_deactivate(fence, &i915_sw_fence_debug_descr);
     79  1.1  riastrad }
     80  1.1  riastrad 
     81  1.1  riastrad static inline void debug_fence_destroy(struct i915_sw_fence *fence)
     82  1.1  riastrad {
     83  1.1  riastrad 	debug_object_destroy(fence, &i915_sw_fence_debug_descr);
     84  1.1  riastrad }
     85  1.1  riastrad 
     86  1.1  riastrad static inline void debug_fence_free(struct i915_sw_fence *fence)
     87  1.1  riastrad {
     88  1.1  riastrad 	debug_object_free(fence, &i915_sw_fence_debug_descr);
     89  1.1  riastrad 	smp_wmb(); /* flush the change in state before reallocation */
     90  1.1  riastrad }
     91  1.1  riastrad 
     92  1.1  riastrad static inline void debug_fence_assert(struct i915_sw_fence *fence)
     93  1.1  riastrad {
     94  1.1  riastrad 	debug_object_assert_init(fence, &i915_sw_fence_debug_descr);
     95  1.1  riastrad }
     96  1.1  riastrad 
     97  1.1  riastrad #else
     98  1.1  riastrad 
     99  1.1  riastrad static inline void debug_fence_init(struct i915_sw_fence *fence)
    100  1.1  riastrad {
    101  1.1  riastrad }
    102  1.1  riastrad 
    103  1.1  riastrad static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
    104  1.1  riastrad {
    105  1.1  riastrad }
    106  1.1  riastrad 
    107  1.1  riastrad static inline void debug_fence_activate(struct i915_sw_fence *fence)
    108  1.1  riastrad {
    109  1.1  riastrad }
    110  1.1  riastrad 
    111  1.1  riastrad static inline void debug_fence_set_state(struct i915_sw_fence *fence,
    112  1.1  riastrad 					 int old, int new)
    113  1.1  riastrad {
    114  1.1  riastrad }
    115  1.1  riastrad 
    116  1.1  riastrad static inline void debug_fence_deactivate(struct i915_sw_fence *fence)
    117  1.1  riastrad {
    118  1.1  riastrad }
    119  1.1  riastrad 
    120  1.1  riastrad static inline void debug_fence_destroy(struct i915_sw_fence *fence)
    121  1.1  riastrad {
    122  1.1  riastrad }
    123  1.1  riastrad 
    124  1.1  riastrad static inline void debug_fence_free(struct i915_sw_fence *fence)
    125  1.1  riastrad {
    126  1.1  riastrad }
    127  1.1  riastrad 
    128  1.1  riastrad static inline void debug_fence_assert(struct i915_sw_fence *fence)
    129  1.1  riastrad {
    130  1.1  riastrad }
    131  1.1  riastrad 
    132  1.1  riastrad #endif
    133  1.1  riastrad 
    134  1.1  riastrad static int __i915_sw_fence_notify(struct i915_sw_fence *fence,
    135  1.1  riastrad 				  enum i915_sw_fence_notify state)
    136  1.1  riastrad {
    137  1.1  riastrad 	i915_sw_fence_notify_t fn;
    138  1.1  riastrad 
    139  1.1  riastrad 	fn = (i915_sw_fence_notify_t)(fence->flags & I915_SW_FENCE_MASK);
    140  1.1  riastrad 	return fn(fence, state);
    141  1.1  riastrad }
    142  1.1  riastrad 
    143  1.1  riastrad void i915_sw_fence_fini(struct i915_sw_fence *fence)
    144  1.1  riastrad {
    145  1.3  riastrad #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS
    146  1.1  riastrad 	debug_fence_free(fence);
    147  1.3  riastrad #endif
    148  1.3  riastrad 	spin_lock_destroy(&fence->wait.lock);
    149  1.3  riastrad 	BUG_ON(!list_empty(&fence->wait.head));
    150  1.3  riastrad }
    151  1.3  riastrad 
    152  1.3  riastrad #ifdef __NetBSD__
    153  1.3  riastrad 
    154  1.3  riastrad /* XXX whattakludge */
    155  1.3  riastrad 
    156  1.3  riastrad typedef struct i915_sw_fence_queue wait_queue_head_t;
    157  1.3  riastrad typedef struct i915_sw_fence_waiter wait_queue_entry_t;
    158  1.3  riastrad 
    159  1.3  riastrad #define	TASK_NORMAL	0
    160  1.3  riastrad 
    161  1.3  riastrad struct i915_sw_fence_wq {
    162  1.3  riastrad 	struct i915_sw_fence *fence;
    163  1.3  riastrad 	drm_waitqueue_t wq;
    164  1.3  riastrad };
    165  1.3  riastrad 
    166  1.3  riastrad static int
    167  1.3  riastrad autoremove_wake_function(struct i915_sw_fence_waiter *waiter, unsigned mode,
    168  1.6  riastrad     int flags, void *donottouch_no_really)
    169  1.3  riastrad {
    170  1.6  riastrad 	struct i915_sw_fence_wq *sfw = waiter->private;
    171  1.3  riastrad 
    172  1.3  riastrad 	/* Caller presumably already completed the fence.  */
    173  1.3  riastrad 	DRM_SPIN_WAKEUP_ALL(&sfw->wq, &sfw->fence->wait.lock);
    174  1.3  riastrad 
    175  1.3  riastrad 	return 0;
    176  1.1  riastrad }
    177  1.3  riastrad 
    178  1.3  riastrad void
    179  1.3  riastrad i915_sw_fence_wait(struct i915_sw_fence *fence)
    180  1.3  riastrad {
    181  1.3  riastrad 	struct i915_sw_fence_waiter waiter;
    182  1.3  riastrad 	struct i915_sw_fence_wq sfw;
    183  1.3  riastrad 	int ret;
    184  1.3  riastrad 
    185  1.3  riastrad 	waiter.flags = 0;
    186  1.3  riastrad 	waiter.func = autoremove_wake_function;
    187  1.3  riastrad 	waiter.private = &sfw;
    188  1.3  riastrad 
    189  1.3  riastrad 	sfw.fence = fence;
    190  1.3  riastrad 	DRM_INIT_WAITQUEUE(&sfw.wq, "i915swf");
    191  1.3  riastrad 
    192  1.3  riastrad 	spin_lock(&fence->wait.lock);
    193  1.4  riastrad 	list_add_tail(&waiter.entry, &fence->wait.head);
    194  1.3  riastrad 	DRM_SPIN_WAIT_NOINTR_UNTIL(ret, &sfw.wq, &fence->wait.lock,
    195  1.3  riastrad 	    i915_sw_fence_done(fence));
    196  1.5  riastrad 	list_del(&waiter.entry);
    197  1.3  riastrad 	spin_unlock(&fence->wait.lock);
    198  1.3  riastrad 
    199  1.3  riastrad 	DRM_DESTROY_WAITQUEUE(&sfw.wq);
    200  1.3  riastrad }
    201  1.3  riastrad 
    202  1.1  riastrad #endif
    203  1.1  riastrad 
    204  1.1  riastrad static void __i915_sw_fence_wake_up_all(struct i915_sw_fence *fence,
    205  1.1  riastrad 					struct list_head *continuation)
    206  1.1  riastrad {
    207  1.1  riastrad 	wait_queue_head_t *x = &fence->wait;
    208  1.1  riastrad 	wait_queue_entry_t *pos, *next;
    209  1.1  riastrad 	unsigned long flags;
    210  1.1  riastrad 
    211  1.1  riastrad 	debug_fence_deactivate(fence);
    212  1.1  riastrad 
    213  1.1  riastrad 	/*
    214  1.1  riastrad 	 * To prevent unbounded recursion as we traverse the graph of
    215  1.1  riastrad 	 * i915_sw_fences, we move the entry list from this, the next ready
    216  1.1  riastrad 	 * fence, to the tail of the original fence's entry list
    217  1.1  riastrad 	 * (and so added to the list to be woken).
    218  1.1  riastrad 	 */
    219  1.1  riastrad 
    220  1.1  riastrad 	spin_lock_irqsave_nested(&x->lock, flags, 1 + !!continuation);
    221  1.3  riastrad 	atomic_set_release(&fence->pending, -1); /* 0 -> -1 [done] */
    222  1.1  riastrad 	if (continuation) {
    223  1.1  riastrad 		list_for_each_entry_safe(pos, next, &x->head, entry) {
    224  1.1  riastrad 			if (pos->func == autoremove_wake_function)
    225  1.1  riastrad 				pos->func(pos, TASK_NORMAL, 0, continuation);
    226  1.1  riastrad 			else
    227  1.1  riastrad 				list_move_tail(&pos->entry, continuation);
    228  1.1  riastrad 		}
    229  1.1  riastrad 	} else {
    230  1.1  riastrad 		LIST_HEAD(extra);
    231  1.1  riastrad 
    232  1.1  riastrad 		do {
    233  1.1  riastrad 			list_for_each_entry_safe(pos, next, &x->head, entry) {
    234  1.1  riastrad 				pos->func(pos,
    235  1.1  riastrad 					  TASK_NORMAL, fence->error,
    236  1.1  riastrad 					  &extra);
    237  1.1  riastrad 			}
    238  1.1  riastrad 
    239  1.1  riastrad 			if (list_empty(&extra))
    240  1.1  riastrad 				break;
    241  1.1  riastrad 
    242  1.1  riastrad 			list_splice_tail_init(&extra, &x->head);
    243  1.1  riastrad 		} while (1);
    244  1.1  riastrad 	}
    245  1.1  riastrad 	spin_unlock_irqrestore(&x->lock, flags);
    246  1.1  riastrad 
    247  1.1  riastrad 	debug_fence_assert(fence);
    248  1.1  riastrad }
    249  1.1  riastrad 
    250  1.1  riastrad static void __i915_sw_fence_complete(struct i915_sw_fence *fence,
    251  1.1  riastrad 				     struct list_head *continuation)
    252  1.1  riastrad {
    253  1.1  riastrad 	debug_fence_assert(fence);
    254  1.1  riastrad 
    255  1.1  riastrad 	if (!atomic_dec_and_test(&fence->pending))
    256  1.1  riastrad 		return;
    257  1.1  riastrad 
    258  1.1  riastrad 	debug_fence_set_state(fence, DEBUG_FENCE_IDLE, DEBUG_FENCE_NOTIFY);
    259  1.1  riastrad 
    260  1.1  riastrad 	if (__i915_sw_fence_notify(fence, FENCE_COMPLETE) != NOTIFY_DONE)
    261  1.1  riastrad 		return;
    262  1.1  riastrad 
    263  1.1  riastrad 	debug_fence_set_state(fence, DEBUG_FENCE_NOTIFY, DEBUG_FENCE_IDLE);
    264  1.1  riastrad 
    265  1.1  riastrad 	__i915_sw_fence_wake_up_all(fence, continuation);
    266  1.1  riastrad 
    267  1.1  riastrad 	debug_fence_destroy(fence);
    268  1.1  riastrad 	__i915_sw_fence_notify(fence, FENCE_FREE);
    269  1.1  riastrad }
    270  1.1  riastrad 
    271  1.1  riastrad void i915_sw_fence_complete(struct i915_sw_fence *fence)
    272  1.1  riastrad {
    273  1.1  riastrad 	debug_fence_assert(fence);
    274  1.1  riastrad 
    275  1.1  riastrad 	if (WARN_ON(i915_sw_fence_done(fence)))
    276  1.1  riastrad 		return;
    277  1.1  riastrad 
    278  1.1  riastrad 	__i915_sw_fence_complete(fence, NULL);
    279  1.1  riastrad }
    280  1.1  riastrad 
    281  1.1  riastrad void i915_sw_fence_await(struct i915_sw_fence *fence)
    282  1.1  riastrad {
    283  1.1  riastrad 	debug_fence_assert(fence);
    284  1.1  riastrad 	WARN_ON(atomic_inc_return(&fence->pending) <= 1);
    285  1.1  riastrad }
    286  1.1  riastrad 
    287  1.1  riastrad void __i915_sw_fence_init(struct i915_sw_fence *fence,
    288  1.1  riastrad 			  i915_sw_fence_notify_t fn,
    289  1.1  riastrad 			  const char *name,
    290  1.1  riastrad 			  struct lock_class_key *key)
    291  1.1  riastrad {
    292  1.1  riastrad 	BUG_ON(!fn || (unsigned long)fn & ~I915_SW_FENCE_MASK);
    293  1.1  riastrad 
    294  1.3  riastrad #ifdef __NetBSD__
    295  1.3  riastrad 	spin_lock_init(&fence->wait.lock);
    296  1.3  riastrad 	INIT_LIST_HEAD(&fence->wait.head);
    297  1.3  riastrad #else
    298  1.1  riastrad 	__init_waitqueue_head(&fence->wait, name, key);
    299  1.3  riastrad #endif
    300  1.1  riastrad 	fence->flags = (unsigned long)fn;
    301  1.1  riastrad 
    302  1.1  riastrad 	i915_sw_fence_reinit(fence);
    303  1.1  riastrad }
    304  1.1  riastrad 
    305  1.1  riastrad void i915_sw_fence_reinit(struct i915_sw_fence *fence)
    306  1.1  riastrad {
    307  1.1  riastrad 	debug_fence_init(fence);
    308  1.1  riastrad 
    309  1.1  riastrad 	atomic_set(&fence->pending, 1);
    310  1.1  riastrad 	fence->error = 0;
    311  1.1  riastrad 
    312  1.1  riastrad 	I915_SW_FENCE_BUG_ON(!fence->flags);
    313  1.1  riastrad 	I915_SW_FENCE_BUG_ON(!list_empty(&fence->wait.head));
    314  1.1  riastrad }
    315  1.1  riastrad 
    316  1.1  riastrad void i915_sw_fence_commit(struct i915_sw_fence *fence)
    317  1.1  riastrad {
    318  1.1  riastrad 	debug_fence_activate(fence);
    319  1.1  riastrad 	i915_sw_fence_complete(fence);
    320  1.1  riastrad }
    321  1.1  riastrad 
    322  1.1  riastrad static int i915_sw_fence_wake(wait_queue_entry_t *wq, unsigned mode, int flags, void *key)
    323  1.1  riastrad {
    324  1.1  riastrad 	i915_sw_fence_set_error_once(wq->private, flags);
    325  1.1  riastrad 
    326  1.1  riastrad 	list_del(&wq->entry);
    327  1.1  riastrad 	__i915_sw_fence_complete(wq->private, key);
    328  1.1  riastrad 
    329  1.1  riastrad 	if (wq->flags & I915_SW_FENCE_FLAG_ALLOC)
    330  1.1  riastrad 		kfree(wq);
    331  1.1  riastrad 	return 0;
    332  1.1  riastrad }
    333  1.1  riastrad 
    334  1.1  riastrad static bool __i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
    335  1.1  riastrad 				    const struct i915_sw_fence * const signaler)
    336  1.1  riastrad {
    337  1.1  riastrad 	wait_queue_entry_t *wq;
    338  1.1  riastrad 
    339  1.1  riastrad 	if (__test_and_set_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags))
    340  1.1  riastrad 		return false;
    341  1.1  riastrad 
    342  1.1  riastrad 	if (fence == signaler)
    343  1.1  riastrad 		return true;
    344  1.1  riastrad 
    345  1.1  riastrad 	list_for_each_entry(wq, &fence->wait.head, entry) {
    346  1.1  riastrad 		if (wq->func != i915_sw_fence_wake)
    347  1.1  riastrad 			continue;
    348  1.1  riastrad 
    349  1.1  riastrad 		if (__i915_sw_fence_check_if_after(wq->private, signaler))
    350  1.1  riastrad 			return true;
    351  1.1  riastrad 	}
    352  1.1  riastrad 
    353  1.1  riastrad 	return false;
    354  1.1  riastrad }
    355  1.1  riastrad 
    356  1.1  riastrad static void __i915_sw_fence_clear_checked_bit(struct i915_sw_fence *fence)
    357  1.1  riastrad {
    358  1.1  riastrad 	wait_queue_entry_t *wq;
    359  1.1  riastrad 
    360  1.1  riastrad 	if (!__test_and_clear_bit(I915_SW_FENCE_CHECKED_BIT, &fence->flags))
    361  1.1  riastrad 		return;
    362  1.1  riastrad 
    363  1.1  riastrad 	list_for_each_entry(wq, &fence->wait.head, entry) {
    364  1.1  riastrad 		if (wq->func != i915_sw_fence_wake)
    365  1.1  riastrad 			continue;
    366  1.1  riastrad 
    367  1.1  riastrad 		__i915_sw_fence_clear_checked_bit(wq->private);
    368  1.1  riastrad 	}
    369  1.1  riastrad }
    370  1.1  riastrad 
    371  1.1  riastrad static bool i915_sw_fence_check_if_after(struct i915_sw_fence *fence,
    372  1.1  riastrad 				  const struct i915_sw_fence * const signaler)
    373  1.1  riastrad {
    374  1.1  riastrad 	unsigned long flags;
    375  1.1  riastrad 	bool err;
    376  1.1  riastrad 
    377  1.1  riastrad 	if (!IS_ENABLED(CONFIG_DRM_I915_SW_FENCE_CHECK_DAG))
    378  1.1  riastrad 		return false;
    379  1.1  riastrad 
    380  1.1  riastrad 	spin_lock_irqsave(&i915_sw_fence_lock, flags);
    381  1.1  riastrad 	err = __i915_sw_fence_check_if_after(fence, signaler);
    382  1.1  riastrad 	__i915_sw_fence_clear_checked_bit(fence);
    383  1.1  riastrad 	spin_unlock_irqrestore(&i915_sw_fence_lock, flags);
    384  1.1  riastrad 
    385  1.1  riastrad 	return err;
    386  1.1  riastrad }
    387  1.1  riastrad 
    388  1.1  riastrad static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
    389  1.1  riastrad 					  struct i915_sw_fence *signaler,
    390  1.1  riastrad 					  wait_queue_entry_t *wq, gfp_t gfp)
    391  1.1  riastrad {
    392  1.1  riastrad 	unsigned long flags;
    393  1.1  riastrad 	int pending;
    394  1.1  riastrad 
    395  1.1  riastrad 	debug_fence_assert(fence);
    396  1.1  riastrad 	might_sleep_if(gfpflags_allow_blocking(gfp));
    397  1.1  riastrad 
    398  1.1  riastrad 	if (i915_sw_fence_done(signaler)) {
    399  1.1  riastrad 		i915_sw_fence_set_error_once(fence, signaler->error);
    400  1.1  riastrad 		return 0;
    401  1.1  riastrad 	}
    402  1.1  riastrad 
    403  1.1  riastrad 	debug_fence_assert(signaler);
    404  1.1  riastrad 
    405  1.1  riastrad 	/* The dependency graph must be acyclic. */
    406  1.1  riastrad 	if (unlikely(i915_sw_fence_check_if_after(fence, signaler)))
    407  1.1  riastrad 		return -EINVAL;
    408  1.1  riastrad 
    409  1.1  riastrad 	pending = 0;
    410  1.1  riastrad 	if (!wq) {
    411  1.1  riastrad 		wq = kmalloc(sizeof(*wq), gfp);
    412  1.1  riastrad 		if (!wq) {
    413  1.1  riastrad 			if (!gfpflags_allow_blocking(gfp))
    414  1.1  riastrad 				return -ENOMEM;
    415  1.1  riastrad 
    416  1.1  riastrad 			i915_sw_fence_wait(signaler);
    417  1.1  riastrad 			i915_sw_fence_set_error_once(fence, signaler->error);
    418  1.1  riastrad 			return 0;
    419  1.1  riastrad 		}
    420  1.1  riastrad 
    421  1.1  riastrad 		pending |= I915_SW_FENCE_FLAG_ALLOC;
    422  1.1  riastrad 	}
    423  1.1  riastrad 
    424  1.1  riastrad 	INIT_LIST_HEAD(&wq->entry);
    425  1.1  riastrad 	wq->flags = pending;
    426  1.1  riastrad 	wq->func = i915_sw_fence_wake;
    427  1.1  riastrad 	wq->private = fence;
    428  1.1  riastrad 
    429  1.1  riastrad 	i915_sw_fence_await(fence);
    430  1.1  riastrad 
    431  1.1  riastrad 	spin_lock_irqsave(&signaler->wait.lock, flags);
    432  1.1  riastrad 	if (likely(!i915_sw_fence_done(signaler))) {
    433  1.3  riastrad #ifdef __NetBSD__
    434  1.3  riastrad 		list_add(&wq->entry, &signaler->wait.head);
    435  1.3  riastrad #else
    436  1.1  riastrad 		__add_wait_queue_entry_tail(&signaler->wait, wq);
    437  1.3  riastrad #endif
    438  1.1  riastrad 		pending = 1;
    439  1.1  riastrad 	} else {
    440  1.1  riastrad 		i915_sw_fence_wake(wq, 0, signaler->error, NULL);
    441  1.1  riastrad 		pending = 0;
    442  1.1  riastrad 	}
    443  1.1  riastrad 	spin_unlock_irqrestore(&signaler->wait.lock, flags);
    444  1.1  riastrad 
    445  1.1  riastrad 	return pending;
    446  1.1  riastrad }
    447  1.1  riastrad 
    448  1.1  riastrad int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
    449  1.1  riastrad 				 struct i915_sw_fence *signaler,
    450  1.1  riastrad 				 wait_queue_entry_t *wq)
    451  1.1  riastrad {
    452  1.1  riastrad 	return __i915_sw_fence_await_sw_fence(fence, signaler, wq, 0);
    453  1.1  riastrad }
    454  1.1  riastrad 
    455  1.1  riastrad int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
    456  1.1  riastrad 				     struct i915_sw_fence *signaler,
    457  1.1  riastrad 				     gfp_t gfp)
    458  1.1  riastrad {
    459  1.1  riastrad 	return __i915_sw_fence_await_sw_fence(fence, signaler, NULL, gfp);
    460  1.1  riastrad }
    461  1.1  riastrad 
    462  1.1  riastrad struct i915_sw_dma_fence_cb_timer {
    463  1.1  riastrad 	struct i915_sw_dma_fence_cb base;
    464  1.1  riastrad 	struct dma_fence *dma;
    465  1.1  riastrad 	struct timer_list timer;
    466  1.1  riastrad 	struct irq_work work;
    467  1.1  riastrad 	struct rcu_head rcu;
    468  1.1  riastrad };
    469  1.1  riastrad 
    470  1.1  riastrad static void dma_i915_sw_fence_wake(struct dma_fence *dma,
    471  1.1  riastrad 				   struct dma_fence_cb *data)
    472  1.1  riastrad {
    473  1.1  riastrad 	struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
    474  1.1  riastrad 
    475  1.1  riastrad 	i915_sw_fence_set_error_once(cb->fence, dma->error);
    476  1.1  riastrad 	i915_sw_fence_complete(cb->fence);
    477  1.1  riastrad 	kfree(cb);
    478  1.1  riastrad }
    479  1.1  riastrad 
    480  1.1  riastrad static void timer_i915_sw_fence_wake(struct timer_list *t)
    481  1.1  riastrad {
    482  1.1  riastrad 	struct i915_sw_dma_fence_cb_timer *cb = from_timer(cb, t, timer);
    483  1.1  riastrad 	struct i915_sw_fence *fence;
    484  1.1  riastrad 
    485  1.1  riastrad 	fence = xchg(&cb->base.fence, NULL);
    486  1.1  riastrad 	if (!fence)
    487  1.1  riastrad 		return;
    488  1.1  riastrad 
    489  1.3  riastrad 	pr_notice("Asynchronous wait on fence %s:%s:%"PRIx64" timed out (hint:%p)\n",
    490  1.1  riastrad 		  cb->dma->ops->get_driver_name(cb->dma),
    491  1.1  riastrad 		  cb->dma->ops->get_timeline_name(cb->dma),
    492  1.3  riastrad 		  (uint64_t)cb->dma->seqno,
    493  1.1  riastrad 		  i915_sw_fence_debug_hint(fence));
    494  1.1  riastrad 
    495  1.1  riastrad 	i915_sw_fence_set_error_once(fence, -ETIMEDOUT);
    496  1.1  riastrad 	i915_sw_fence_complete(fence);
    497  1.1  riastrad }
    498  1.1  riastrad 
    499  1.1  riastrad static void dma_i915_sw_fence_wake_timer(struct dma_fence *dma,
    500  1.1  riastrad 					 struct dma_fence_cb *data)
    501  1.1  riastrad {
    502  1.1  riastrad 	struct i915_sw_dma_fence_cb_timer *cb =
    503  1.1  riastrad 		container_of(data, typeof(*cb), base.base);
    504  1.1  riastrad 	struct i915_sw_fence *fence;
    505  1.1  riastrad 
    506  1.1  riastrad 	fence = xchg(&cb->base.fence, NULL);
    507  1.1  riastrad 	if (fence) {
    508  1.1  riastrad 		i915_sw_fence_set_error_once(fence, dma->error);
    509  1.1  riastrad 		i915_sw_fence_complete(fence);
    510  1.1  riastrad 	}
    511  1.1  riastrad 
    512  1.1  riastrad 	irq_work_queue(&cb->work);
    513  1.1  riastrad }
    514  1.1  riastrad 
    515  1.1  riastrad static void irq_i915_sw_fence_work(struct irq_work *wrk)
    516  1.1  riastrad {
    517  1.1  riastrad 	struct i915_sw_dma_fence_cb_timer *cb =
    518  1.1  riastrad 		container_of(wrk, typeof(*cb), work);
    519  1.1  riastrad 
    520  1.1  riastrad 	del_timer_sync(&cb->timer);
    521  1.1  riastrad 	dma_fence_put(cb->dma);
    522  1.1  riastrad 
    523  1.1  riastrad 	kfree_rcu(cb, rcu);
    524  1.1  riastrad }
    525  1.1  riastrad 
    526  1.1  riastrad int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
    527  1.1  riastrad 				  struct dma_fence *dma,
    528  1.1  riastrad 				  unsigned long timeout,
    529  1.1  riastrad 				  gfp_t gfp)
    530  1.1  riastrad {
    531  1.1  riastrad 	struct i915_sw_dma_fence_cb *cb;
    532  1.1  riastrad 	dma_fence_func_t func;
    533  1.1  riastrad 	int ret;
    534  1.1  riastrad 
    535  1.1  riastrad 	debug_fence_assert(fence);
    536  1.1  riastrad 	might_sleep_if(gfpflags_allow_blocking(gfp));
    537  1.1  riastrad 
    538  1.1  riastrad 	if (dma_fence_is_signaled(dma)) {
    539  1.1  riastrad 		i915_sw_fence_set_error_once(fence, dma->error);
    540  1.1  riastrad 		return 0;
    541  1.1  riastrad 	}
    542  1.1  riastrad 
    543  1.1  riastrad 	cb = kmalloc(timeout ?
    544  1.1  riastrad 		     sizeof(struct i915_sw_dma_fence_cb_timer) :
    545  1.1  riastrad 		     sizeof(struct i915_sw_dma_fence_cb),
    546  1.1  riastrad 		     gfp);
    547  1.1  riastrad 	if (!cb) {
    548  1.1  riastrad 		if (!gfpflags_allow_blocking(gfp))
    549  1.1  riastrad 			return -ENOMEM;
    550  1.1  riastrad 
    551  1.1  riastrad 		ret = dma_fence_wait(dma, false);
    552  1.1  riastrad 		if (ret)
    553  1.1  riastrad 			return ret;
    554  1.1  riastrad 
    555  1.1  riastrad 		i915_sw_fence_set_error_once(fence, dma->error);
    556  1.1  riastrad 		return 0;
    557  1.1  riastrad 	}
    558  1.1  riastrad 
    559  1.1  riastrad 	cb->fence = fence;
    560  1.1  riastrad 	i915_sw_fence_await(fence);
    561  1.1  riastrad 
    562  1.1  riastrad 	func = dma_i915_sw_fence_wake;
    563  1.1  riastrad 	if (timeout) {
    564  1.1  riastrad 		struct i915_sw_dma_fence_cb_timer *timer =
    565  1.1  riastrad 			container_of(cb, typeof(*timer), base);
    566  1.1  riastrad 
    567  1.1  riastrad 		timer->dma = dma_fence_get(dma);
    568  1.1  riastrad 		init_irq_work(&timer->work, irq_i915_sw_fence_work);
    569  1.1  riastrad 
    570  1.1  riastrad 		timer_setup(&timer->timer,
    571  1.1  riastrad 			    timer_i915_sw_fence_wake, TIMER_IRQSAFE);
    572  1.1  riastrad 		mod_timer(&timer->timer, round_jiffies_up(jiffies + timeout));
    573  1.1  riastrad 
    574  1.1  riastrad 		func = dma_i915_sw_fence_wake_timer;
    575  1.1  riastrad 	}
    576  1.1  riastrad 
    577  1.1  riastrad 	ret = dma_fence_add_callback(dma, &cb->base, func);
    578  1.1  riastrad 	if (ret == 0) {
    579  1.1  riastrad 		ret = 1;
    580  1.1  riastrad 	} else {
    581  1.1  riastrad 		func(dma, &cb->base);
    582  1.1  riastrad 		if (ret == -ENOENT) /* fence already signaled */
    583  1.1  riastrad 			ret = 0;
    584  1.1  riastrad 	}
    585  1.1  riastrad 
    586  1.1  riastrad 	return ret;
    587  1.1  riastrad }
    588  1.1  riastrad 
    589  1.1  riastrad static void __dma_i915_sw_fence_wake(struct dma_fence *dma,
    590  1.1  riastrad 				     struct dma_fence_cb *data)
    591  1.1  riastrad {
    592  1.1  riastrad 	struct i915_sw_dma_fence_cb *cb = container_of(data, typeof(*cb), base);
    593  1.1  riastrad 
    594  1.1  riastrad 	i915_sw_fence_set_error_once(cb->fence, dma->error);
    595  1.1  riastrad 	i915_sw_fence_complete(cb->fence);
    596  1.1  riastrad }
    597  1.1  riastrad 
    598  1.1  riastrad int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
    599  1.1  riastrad 				    struct dma_fence *dma,
    600  1.1  riastrad 				    struct i915_sw_dma_fence_cb *cb)
    601  1.1  riastrad {
    602  1.1  riastrad 	int ret;
    603  1.1  riastrad 
    604  1.1  riastrad 	debug_fence_assert(fence);
    605  1.1  riastrad 
    606  1.1  riastrad 	if (dma_fence_is_signaled(dma)) {
    607  1.1  riastrad 		i915_sw_fence_set_error_once(fence, dma->error);
    608  1.1  riastrad 		return 0;
    609  1.1  riastrad 	}
    610  1.1  riastrad 
    611  1.1  riastrad 	cb->fence = fence;
    612  1.1  riastrad 	i915_sw_fence_await(fence);
    613  1.1  riastrad 
    614  1.1  riastrad 	ret = dma_fence_add_callback(dma, &cb->base, __dma_i915_sw_fence_wake);
    615  1.1  riastrad 	if (ret == 0) {
    616  1.1  riastrad 		ret = 1;
    617  1.1  riastrad 	} else {
    618  1.1  riastrad 		__dma_i915_sw_fence_wake(dma, &cb->base);
    619  1.1  riastrad 		if (ret == -ENOENT) /* fence already signaled */
    620  1.1  riastrad 			ret = 0;
    621  1.1  riastrad 	}
    622  1.1  riastrad 
    623  1.1  riastrad 	return ret;
    624  1.1  riastrad }
    625  1.1  riastrad 
    626  1.1  riastrad int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
    627  1.1  riastrad 				    struct dma_resv *resv,
    628  1.1  riastrad 				    const struct dma_fence_ops *exclude,
    629  1.1  riastrad 				    bool write,
    630  1.1  riastrad 				    unsigned long timeout,
    631  1.1  riastrad 				    gfp_t gfp)
    632  1.1  riastrad {
    633  1.1  riastrad 	struct dma_fence *excl;
    634  1.1  riastrad 	int ret = 0, pending;
    635  1.1  riastrad 
    636  1.1  riastrad 	debug_fence_assert(fence);
    637  1.1  riastrad 	might_sleep_if(gfpflags_allow_blocking(gfp));
    638  1.1  riastrad 
    639  1.1  riastrad 	if (write) {
    640  1.1  riastrad 		struct dma_fence **shared;
    641  1.1  riastrad 		unsigned int count, i;
    642  1.1  riastrad 
    643  1.1  riastrad 		ret = dma_resv_get_fences_rcu(resv, &excl, &count, &shared);
    644  1.1  riastrad 		if (ret)
    645  1.1  riastrad 			return ret;
    646  1.1  riastrad 
    647  1.1  riastrad 		for (i = 0; i < count; i++) {
    648  1.1  riastrad 			if (shared[i]->ops == exclude)
    649  1.1  riastrad 				continue;
    650  1.1  riastrad 
    651  1.1  riastrad 			pending = i915_sw_fence_await_dma_fence(fence,
    652  1.1  riastrad 								shared[i],
    653  1.1  riastrad 								timeout,
    654  1.1  riastrad 								gfp);
    655  1.1  riastrad 			if (pending < 0) {
    656  1.1  riastrad 				ret = pending;
    657  1.1  riastrad 				break;
    658  1.1  riastrad 			}
    659  1.1  riastrad 
    660  1.1  riastrad 			ret |= pending;
    661  1.1  riastrad 		}
    662  1.1  riastrad 
    663  1.1  riastrad 		for (i = 0; i < count; i++)
    664  1.1  riastrad 			dma_fence_put(shared[i]);
    665  1.1  riastrad 		kfree(shared);
    666  1.1  riastrad 	} else {
    667  1.1  riastrad 		excl = dma_resv_get_excl_rcu(resv);
    668  1.1  riastrad 	}
    669  1.1  riastrad 
    670  1.1  riastrad 	if (ret >= 0 && excl && excl->ops != exclude) {
    671  1.1  riastrad 		pending = i915_sw_fence_await_dma_fence(fence,
    672  1.1  riastrad 							excl,
    673  1.1  riastrad 							timeout,
    674  1.1  riastrad 							gfp);
    675  1.1  riastrad 		if (pending < 0)
    676  1.1  riastrad 			ret = pending;
    677  1.1  riastrad 		else
    678  1.1  riastrad 			ret |= pending;
    679  1.1  riastrad 	}
    680  1.1  riastrad 
    681  1.1  riastrad 	dma_fence_put(excl);
    682  1.1  riastrad 
    683  1.1  riastrad 	return ret;
    684  1.1  riastrad }
    685  1.1  riastrad 
    686  1.1  riastrad #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
    687  1.1  riastrad #include "selftests/lib_sw_fence.c"
    688  1.1  riastrad #include "selftests/i915_sw_fence.c"
    689  1.1  riastrad #endif
    690