0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "lib_sw_fence.h"
0026
0027
0028
0029 static int
0030 nop_fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
0031 {
0032 return NOTIFY_DONE;
0033 }
0034
0035 void __onstack_fence_init(struct i915_sw_fence *fence,
0036 const char *name,
0037 struct lock_class_key *key)
0038 {
0039 debug_fence_init_onstack(fence);
0040
0041 __init_waitqueue_head(&fence->wait, name, key);
0042 atomic_set(&fence->pending, 1);
0043 fence->error = 0;
0044 fence->fn = nop_fence_notify;
0045 }
0046
0047 void onstack_fence_fini(struct i915_sw_fence *fence)
0048 {
0049 if (!fence->fn)
0050 return;
0051
0052 i915_sw_fence_commit(fence);
0053 i915_sw_fence_fini(fence);
0054 }
0055
0056 static void timed_fence_wake(struct timer_list *t)
0057 {
0058 struct timed_fence *tf = from_timer(tf, t, timer);
0059
0060 i915_sw_fence_commit(&tf->fence);
0061 }
0062
0063 void timed_fence_init(struct timed_fence *tf, unsigned long expires)
0064 {
0065 onstack_fence_init(&tf->fence);
0066
0067 timer_setup_on_stack(&tf->timer, timed_fence_wake, 0);
0068
0069 if (time_after(expires, jiffies))
0070 mod_timer(&tf->timer, expires);
0071 else
0072 i915_sw_fence_commit(&tf->fence);
0073 }
0074
0075 void timed_fence_fini(struct timed_fence *tf)
0076 {
0077 if (del_timer_sync(&tf->timer))
0078 i915_sw_fence_commit(&tf->fence);
0079
0080 destroy_timer_on_stack(&tf->timer);
0081 i915_sw_fence_fini(&tf->fence);
0082 }
0083
0084 struct heap_fence {
0085 struct i915_sw_fence fence;
0086 union {
0087 struct kref ref;
0088 struct rcu_head rcu;
0089 };
0090 };
0091
0092 static int
0093 heap_fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state)
0094 {
0095 struct heap_fence *h = container_of(fence, typeof(*h), fence);
0096
0097 switch (state) {
0098 case FENCE_COMPLETE:
0099 break;
0100
0101 case FENCE_FREE:
0102 heap_fence_put(&h->fence);
0103 }
0104
0105 return NOTIFY_DONE;
0106 }
0107
0108 struct i915_sw_fence *heap_fence_create(gfp_t gfp)
0109 {
0110 struct heap_fence *h;
0111
0112 h = kmalloc(sizeof(*h), gfp);
0113 if (!h)
0114 return NULL;
0115
0116 i915_sw_fence_init(&h->fence, heap_fence_notify);
0117 refcount_set(&h->ref.refcount, 2);
0118
0119 return &h->fence;
0120 }
0121
0122 static void heap_fence_release(struct kref *ref)
0123 {
0124 struct heap_fence *h = container_of(ref, typeof(*h), ref);
0125
0126 i915_sw_fence_fini(&h->fence);
0127
0128 kfree_rcu(h, rcu);
0129 }
0130
0131 void heap_fence_put(struct i915_sw_fence *fence)
0132 {
0133 struct heap_fence *h = container_of(fence, typeof(*h), fence);
0134
0135 kref_put(&h->ref, heap_fence_release);
0136 }