Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 1 | /* |
Jonathan Gray | 635b3bc | 2018-11-29 12:30:51 +1100 | [diff] [blame] | 2 | * SPDX-License-Identifier: MIT |
| 3 | * |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 4 | * i915_sw_fence.h - library routines for N:M synchronisation points |
| 5 | * |
| 6 | * Copyright (C) 2016 Intel Corporation |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 7 | */ |
| 8 | |
| 9 | #ifndef _I915_SW_FENCE_H_ |
| 10 | #define _I915_SW_FENCE_H_ |
| 11 | |
Chris Wilson | ea593db | 2019-03-22 09:23:25 +0000 | [diff] [blame] | 12 | #include <linux/dma-fence.h> |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 13 | #include <linux/gfp.h> |
| 14 | #include <linux/kref.h> |
| 15 | #include <linux/notifier.h> /* for NOTIFY_DONE */ |
| 16 | #include <linux/wait.h> |
| 17 | |
| 18 | struct completion; |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 19 | struct reservation_object; |
| 20 | |
| 21 | struct i915_sw_fence { |
| 22 | wait_queue_head_t wait; |
| 23 | unsigned long flags; |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 24 | atomic_t pending; |
| 25 | }; |
| 26 | |
| 27 | #define I915_SW_FENCE_CHECKED_BIT 0 /* used internally for DAG checking */ |
| 28 | #define I915_SW_FENCE_PRIVATE_BIT 1 /* available for use by owner */ |
| 29 | #define I915_SW_FENCE_MASK (~3) |
| 30 | |
| 31 | enum i915_sw_fence_notify { |
| 32 | FENCE_COMPLETE, |
| 33 | FENCE_FREE |
| 34 | }; |
| 35 | |
| 36 | typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *, |
| 37 | enum i915_sw_fence_notify state); |
| 38 | #define __i915_sw_fence_call __aligned(4) |
| 39 | |
Chris Wilson | 556b748 | 2016-11-14 20:40:56 +0000 | [diff] [blame] | 40 | void __i915_sw_fence_init(struct i915_sw_fence *fence, |
| 41 | i915_sw_fence_notify_t fn, |
| 42 | const char *name, |
| 43 | struct lock_class_key *key); |
| 44 | #ifdef CONFIG_LOCKDEP |
| 45 | #define i915_sw_fence_init(fence, fn) \ |
| 46 | do { \ |
| 47 | static struct lock_class_key __key; \ |
| 48 | \ |
| 49 | __i915_sw_fence_init((fence), (fn), #fence, &__key); \ |
| 50 | } while (0) |
| 51 | #else |
| 52 | #define i915_sw_fence_init(fence, fn) \ |
| 53 | __i915_sw_fence_init((fence), (fn), NULL, NULL) |
| 54 | #endif |
| 55 | |
Chris Wilson | fc15840 | 2016-11-25 13:17:18 +0000 | [diff] [blame] | 56 | #ifdef CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS |
| 57 | void i915_sw_fence_fini(struct i915_sw_fence *fence); |
| 58 | #else |
| 59 | static inline void i915_sw_fence_fini(struct i915_sw_fence *fence) {} |
| 60 | #endif |
| 61 | |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 62 | void i915_sw_fence_commit(struct i915_sw_fence *fence); |
| 63 | |
| 64 | int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, |
| 65 | struct i915_sw_fence *after, |
Ingo Molnar | ac6424b | 2017-06-20 12:06:13 +0200 | [diff] [blame] | 66 | wait_queue_entry_t *wq); |
Chris Wilson | 7e94186 | 2016-10-28 13:58:25 +0100 | [diff] [blame] | 67 | int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence, |
| 68 | struct i915_sw_fence *after, |
| 69 | gfp_t gfp); |
Chris Wilson | ea593db | 2019-03-22 09:23:25 +0000 | [diff] [blame] | 70 | |
| 71 | struct i915_sw_dma_fence_cb { |
| 72 | struct dma_fence_cb base; |
| 73 | struct i915_sw_fence *fence; |
| 74 | }; |
| 75 | |
| 76 | int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
| 77 | struct dma_fence *dma, |
| 78 | struct i915_sw_dma_fence_cb *cb); |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 79 | int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence, |
Chris Wilson | f54d186 | 2016-10-25 13:00:45 +0100 | [diff] [blame] | 80 | struct dma_fence *dma, |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 81 | unsigned long timeout, |
| 82 | gfp_t gfp); |
Chris Wilson | ea593db | 2019-03-22 09:23:25 +0000 | [diff] [blame] | 83 | |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 84 | int i915_sw_fence_await_reservation(struct i915_sw_fence *fence, |
| 85 | struct reservation_object *resv, |
Chris Wilson | f54d186 | 2016-10-25 13:00:45 +0100 | [diff] [blame] | 86 | const struct dma_fence_ops *exclude, |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 87 | bool write, |
| 88 | unsigned long timeout, |
| 89 | gfp_t gfp); |
| 90 | |
Chris Wilson | e886196 | 2019-03-01 17:09:00 +0000 | [diff] [blame] | 91 | void i915_sw_fence_await(struct i915_sw_fence *fence); |
| 92 | void i915_sw_fence_complete(struct i915_sw_fence *fence); |
| 93 | |
Chris Wilson | 48bc2a4 | 2016-11-25 13:17:17 +0000 | [diff] [blame] | 94 | static inline bool i915_sw_fence_signaled(const struct i915_sw_fence *fence) |
| 95 | { |
| 96 | return atomic_read(&fence->pending) <= 0; |
| 97 | } |
| 98 | |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 99 | static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence) |
| 100 | { |
| 101 | return atomic_read(&fence->pending) < 0; |
| 102 | } |
| 103 | |
Chris Wilson | 7e94186 | 2016-10-28 13:58:25 +0100 | [diff] [blame] | 104 | static inline void i915_sw_fence_wait(struct i915_sw_fence *fence) |
| 105 | { |
| 106 | wait_event(fence->wait, i915_sw_fence_done(fence)); |
| 107 | } |
| 108 | |
Chris Wilson | e68a139 | 2016-09-09 14:11:41 +0100 | [diff] [blame] | 109 | #endif /* _I915_SW_FENCE_H_ */ |