.. | .. |
---|
40 | 40 | |
---|
41 | 41 | __init_waitqueue_head(&fence->wait, name, key); |
---|
42 | 42 | atomic_set(&fence->pending, 1); |
---|
| 43 | + fence->error = 0; |
---|
43 | 44 | fence->flags = (unsigned long)nop_fence_notify; |
---|
44 | 45 | } |
---|
45 | 46 | |
---|
46 | 47 | void onstack_fence_fini(struct i915_sw_fence *fence) |
---|
47 | 48 | { |
---|
| 49 | + if (!fence->flags) |
---|
| 50 | + return; |
---|
| 51 | + |
---|
48 | 52 | i915_sw_fence_commit(fence); |
---|
49 | 53 | i915_sw_fence_fini(fence); |
---|
50 | 54 | } |
---|
.. | .. |
---|
76 | 80 | destroy_timer_on_stack(&tf->timer); |
---|
77 | 81 | i915_sw_fence_fini(&tf->fence); |
---|
78 | 82 | } |
---|
| 83 | + |
---|
| 84 | +struct heap_fence { |
---|
| 85 | + struct i915_sw_fence fence; |
---|
| 86 | + union { |
---|
| 87 | + struct kref ref; |
---|
| 88 | + struct rcu_head rcu; |
---|
| 89 | + }; |
---|
| 90 | +}; |
---|
| 91 | + |
---|
| 92 | +static int __i915_sw_fence_call |
---|
| 93 | +heap_fence_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) |
---|
| 94 | +{ |
---|
| 95 | + struct heap_fence *h = container_of(fence, typeof(*h), fence); |
---|
| 96 | + |
---|
| 97 | + switch (state) { |
---|
| 98 | + case FENCE_COMPLETE: |
---|
| 99 | + break; |
---|
| 100 | + |
---|
| 101 | + case FENCE_FREE: |
---|
| 102 | + heap_fence_put(&h->fence); |
---|
| 103 | + } |
---|
| 104 | + |
---|
| 105 | + return NOTIFY_DONE; |
---|
| 106 | +} |
---|
| 107 | + |
---|
| 108 | +struct i915_sw_fence *heap_fence_create(gfp_t gfp) |
---|
| 109 | +{ |
---|
| 110 | + struct heap_fence *h; |
---|
| 111 | + |
---|
| 112 | + h = kmalloc(sizeof(*h), gfp); |
---|
| 113 | + if (!h) |
---|
| 114 | + return NULL; |
---|
| 115 | + |
---|
| 116 | + i915_sw_fence_init(&h->fence, heap_fence_notify); |
---|
| 117 | + refcount_set(&h->ref.refcount, 2); |
---|
| 118 | + |
---|
| 119 | + return &h->fence; |
---|
| 120 | +} |
---|
| 121 | + |
---|
| 122 | +static void heap_fence_release(struct kref *ref) |
---|
| 123 | +{ |
---|
| 124 | + struct heap_fence *h = container_of(ref, typeof(*h), ref); |
---|
| 125 | + |
---|
| 126 | + i915_sw_fence_fini(&h->fence); |
---|
| 127 | + |
---|
| 128 | + kfree_rcu(h, rcu); |
---|
| 129 | +} |
---|
| 130 | + |
---|
| 131 | +void heap_fence_put(struct i915_sw_fence *fence) |
---|
| 132 | +{ |
---|
| 133 | + struct heap_fence *h = container_of(fence, typeof(*h), fence); |
---|
| 134 | + |
---|
| 135 | + kref_put(&h->ref, heap_fence_release); |
---|
| 136 | +} |
---|