| .. | .. |
|---|
| 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 | +} |
|---|