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
This commit is contained in:
@@ -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;
|
||||
|
Reference in New Issue
Block a user