diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-17 11:30:22 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-17 13:46:33 -0400 |
commit | f2cb60e9a3881e679465f84140754bc9d29956ea (patch) | |
tree | 62b3bc44752ee688d651354aedf6742ffb8b51e0 /drivers/dma-buf/dma-fence.c | |
parent | 0fc89b6802ba1fcc561b0c906e0cefd384e3b2e5 (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.c | 16 |
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); | |||
129 | int dma_fence_signal_locked(struct dma_fence *fence) | 129 | int 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), |