aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/include/linux/dma-fence.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-08-17 16:30:22 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2019-08-17 18:46:33 +0100
commitf2cb60e9a3881e679465f84140754bc9d29956ea (patch)
tree62b3bc44752ee688d651354aedf6742ffb8b51e0 /include/linux/dma-fence.h
parentdma-fence: Simply wrap dma_fence_signal_locked with dma_fence_signal (diff)
downloadwireguard-linux-f2cb60e9a3881e679465f84140754bc9d29956ea.tar.xz
wireguard-linux-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/linux/dma-fence.h')
-rw-r--r--include/linux/dma-fence.h24
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;