diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-17 16:30:22 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-17 18:46:33 +0100 |
commit | f2cb60e9a3881e679465f84140754bc9d29956ea (patch) | |
tree | 62b3bc44752ee688d651354aedf6742ffb8b51e0 /include | |
parent | 0fc89b6802ba1fcc561b0c906e0cefd384e3b2e5 (diff) | |
download | linux-stable-f2cb60e9a3881e679465f84140754bc9d29956ea.tar.gz linux-stable-f2cb60e9a3881e679465f84140754bc9d29956ea.tar.bz2 linux-stable-f2cb60e9a3881e679465f84140754bc9d29956ea.zip |
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 'include')
-rw-r--r-- | include/linux/dma-fence.h | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h index 2ce4d877d33e..3347c54f3a87 100644 --- a/include/linux/dma-fence.h +++ b/include/linux/dma-fence.h @@ -65,17 +65,31 @@ struct dma_fence_cb; struct dma_fence { spinlock_t *lock; const struct dma_fence_ops *ops; - /* We clear the callback list on kref_put so that by the time we - * release the fence it is unused. No one should be adding to the cb_list - * that they don't themselves hold a reference for. + /* + * We clear the callback list on kref_put so that by the time we + * release the fence it is unused. No one should be adding to the + * cb_list that they don't themselves hold a reference for. + * + * The lifetime of the timestamp is similarly tied to both the + * rcu freelist and the cb_list. The timestamp is only set upon + * signaling while simultaneously notifying the cb_list. Ergo, we + * only use either the cb_list of timestamp. Upon destruction, + * neither are accessible, and so we can use the rcu. This means + * that the cb_list is *only* valid until the signal bit is set, + * and to read either you *must* hold a reference to the fence, + * and not just the rcu_read_lock. + * + * Listed in chronological order. */ union { - struct rcu_head rcu; struct list_head cb_list; + /* @cb_list replaced by @timestamp on dma_fence_signal() */ + ktime_t timestamp; + /* @timestamp replaced by @rcu on dma_fence_release() */ + struct rcu_head rcu; }; u64 context; u64 seqno; - ktime_t timestamp; unsigned long flags; struct kref refcount; int error; |