summaryrefslogtreecommitdiffstats
path: root/drivers/dma-buf/dma-fence.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-08-17 11:30:22 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2019-08-17 13:46:33 -0400
commitf2cb60e9a3881e679465f84140754bc9d29956ea (patch)
tree62b3bc44752ee688d651354aedf6742ffb8b51e0 /drivers/dma-buf/dma-fence.c
parent0fc89b6802ba1fcc561b0c906e0cefd384e3b2e5 (diff)
dma-fence: Store the timestamp in the same union as the cb_list
The timestamp and the cb_list are mutually exclusive, the cb_list can only be added to prior to being signaled (and once signaled we drain), while the timestamp is only valid upon being signaled. Both the timestamp and the cb_list are only valid while the fence is alive, and as soon as no references are held can be replaced by the rcu_head. By reusing the union for the timestamp, we squeeze the base dma_fence struct to 64 bytes on x86-64. v2: Sort the union chronologically Suggested-by: Christian König <christian.koenig@amd.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Christian König <christian.koenig@amd.com> Acked-by: Christian König <christian.koenig@amd.com>. Link: https://patchwork.freedesktop.org/patch/msgid/20190817153022.5749-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/dma-buf/dma-fence.c')
-rw-r--r--drivers/dma-buf/dma-fence.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 8a6d0250285d..2c136aee3e79 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -129,6 +129,7 @@ EXPORT_SYMBOL(dma_fence_context_alloc);
129int dma_fence_signal_locked(struct dma_fence *fence) 129int dma_fence_signal_locked(struct dma_fence *fence)
130{ 130{
131 struct dma_fence_cb *cur, *tmp; 131 struct dma_fence_cb *cur, *tmp;
132 struct list_head cb_list;
132 133
133 lockdep_assert_held(fence->lock); 134 lockdep_assert_held(fence->lock);
134 135
@@ -136,16 +137,16 @@ int dma_fence_signal_locked(struct dma_fence *fence)
136 &fence->flags))) 137 &fence->flags)))
137 return -EINVAL; 138 return -EINVAL;
138 139
140 /* Stash the cb_list before replacing it with the timestamp */
141 list_replace(&fence->cb_list, &cb_list);
142
139 fence->timestamp = ktime_get(); 143 fence->timestamp = ktime_get();
140 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags); 144 set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
141 trace_dma_fence_signaled(fence); 145 trace_dma_fence_signaled(fence);
142 146
143 if (!list_empty(&fence->cb_list)) { 147 list_for_each_entry_safe(cur, tmp, &cb_list, node) {
144 list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) { 148 INIT_LIST_HEAD(&cur->node);
145 INIT_LIST_HEAD(&cur->node); 149 cur->func(fence, cur);
146 cur->func(fence, cur);
147 }
148 INIT_LIST_HEAD(&fence->cb_list);
149 } 150 }
150 151
151 return 0; 152 return 0;
@@ -231,7 +232,8 @@ void dma_fence_release(struct kref *kref)
231 232
232 trace_dma_fence_destroy(fence); 233 trace_dma_fence_destroy(fence);
233 234
234 if (WARN(!list_empty(&fence->cb_list), 235 if (WARN(!list_empty(&fence->cb_list) &&
236 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags),
235 "Fence %s:%s:%llx:%llx released with pending signals!\n", 237 "Fence %s:%s:%llx:%llx released with pending signals!\n",
236 fence->ops->get_driver_name(fence), 238 fence->ops->get_driver_name(fence),
237 fence->ops->get_timeline_name(fence), 239 fence->ops->get_timeline_name(fence),