All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Koenig, Christian" <Christian.Koenig@amd.com>
To: Chris Wilson <chris@chris-wilson.co.uk>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>
Cc: "intel-gfx@lists.freedesktop.org" <intel-gfx@lists.freedesktop.org>
Subject: Re: [PATCH v2] dma-fence: Store the timestamp in the same union as the cb_list
Date: Sat, 17 Aug 2019 15:40:15 +0000	[thread overview]
Message-ID: <b8479897-2543-d965-004b-d46b7fc2ea39@amd.com> (raw)
In-Reply-To: <20190817153022.5749-1-chris@chris-wilson.co.uk>

Am 17.08.19 um 17:30 schrieb Chris Wilson:
> 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>

I can't judge about the correctness of the vmw and Intel stuff, so only 
Acked-by: Christian König <christian.koenig@amd.com>.

> ---
>   drivers/dma-buf/dma-fence.c                 | 16 +++++++-------
>   drivers/gpu/drm/i915/gt/intel_breadcrumbs.c | 13 ++++++------
>   drivers/gpu/drm/vmwgfx/vmwgfx_fence.c       |  3 +++
>   include/linux/dma-fence.h                   | 23 ++++++++++++++++-----
>   4 files changed, 37 insertions(+), 18 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);
>   int dma_fence_signal_locked(struct dma_fence *fence)
>   {
>   	struct dma_fence_cb *cur, *tmp;
> +	struct list_head cb_list;
>   
>   	lockdep_assert_held(fence->lock);
>   
> @@ -136,16 +137,16 @@ int dma_fence_signal_locked(struct dma_fence *fence)
>   				      &fence->flags)))
>   		return -EINVAL;
>   
> +	/* Stash the cb_list before replacing it with the timestamp */
> +	list_replace(&fence->cb_list, &cb_list);
> +
>   	fence->timestamp = ktime_get();
>   	set_bit(DMA_FENCE_FLAG_TIMESTAMP_BIT, &fence->flags);
>   	trace_dma_fence_signaled(fence);
>   
> -	if (!list_empty(&fence->cb_list)) {
> -		list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
> -			INIT_LIST_HEAD(&cur->node);
> -			cur->func(fence, cur);
> -		}
> -		INIT_LIST_HEAD(&fence->cb_list);
> +	list_for_each_entry_safe(cur, tmp, &cb_list, node) {
> +		INIT_LIST_HEAD(&cur->node);
> +		cur->func(fence, cur);
>   	}
>   
>   	return 0;
> @@ -231,7 +232,8 @@ void dma_fence_release(struct kref *kref)
>   
>   	trace_dma_fence_destroy(fence);
>   
> -	if (WARN(!list_empty(&fence->cb_list),
> +	if (WARN(!list_empty(&fence->cb_list) &&
> +		 !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags),
>   		 "Fence %s:%s:%llx:%llx released with pending signals!\n",
>   		 fence->ops->get_driver_name(fence),
>   		 fence->ops->get_timeline_name(fence),
> diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> index 2bc9c460e78d..09c68dda2098 100644
> --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
> @@ -114,18 +114,18 @@ __dma_fence_signal__timestamp(struct dma_fence *fence, ktime_t timestamp)
>   }
>   
>   static void
> -__dma_fence_signal__notify(struct dma_fence *fence)
> +__dma_fence_signal__notify(struct dma_fence *fence,
> +			   const struct list_head *list)
>   {
>   	struct dma_fence_cb *cur, *tmp;
>   
>   	lockdep_assert_held(fence->lock);
>   	lockdep_assert_irqs_disabled();
>   
> -	list_for_each_entry_safe(cur, tmp, &fence->cb_list, node) {
> +	list_for_each_entry_safe(cur, tmp, list, node) {
>   		INIT_LIST_HEAD(&cur->node);
>   		cur->func(fence, cur);
>   	}
> -	INIT_LIST_HEAD(&fence->cb_list);
>   }
>   
>   void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
> @@ -187,11 +187,12 @@ void intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
>   	list_for_each_safe(pos, next, &signal) {
>   		struct i915_request *rq =
>   			list_entry(pos, typeof(*rq), signal_link);
> -
> -		__dma_fence_signal__timestamp(&rq->fence, timestamp);
> +		struct list_head cb_list;
>   
>   		spin_lock(&rq->lock);
> -		__dma_fence_signal__notify(&rq->fence);
> +		list_replace(&rq->fence.cb_list, &cb_list);
> +		__dma_fence_signal__timestamp(&rq->fence, timestamp);
> +		__dma_fence_signal__notify(&rq->fence, &cb_list);
>   		spin_unlock(&rq->lock);
>   
>   		i915_request_put(rq);
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> index 434dfadb0e52..178a6cd1a06f 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
> @@ -185,6 +185,9 @@ static long vmw_fence_wait(struct dma_fence *f, bool intr, signed long timeout)
>   
>   	spin_lock(f->lock);
>   
> +	if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &f->flags))
> +		goto out;
> +
>   	if (intr && signal_pending(current)) {
>   		ret = -ERESTARTSYS;
>   		goto out;
> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
> index 2ce4d877d33e..8b4a5aaa6848 100644
> --- a/include/linux/dma-fence.h
> +++ b/include/linux/dma-fence.h
> @@ -65,17 +65,30 @@ 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.
> +	 *
> +	 * 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;

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2019-08-17 15:40 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-17 14:47 [PATCH 1/6] dma-buf: Introduce selftesting framework Chris Wilson
2019-08-17 14:47 ` [PATCH 2/6] dma-buf: Add selftests for dma-fence Chris Wilson
2019-08-17 14:47 ` [PATCH 3/6] dma-fence: Shrink size of struct dma_fence Chris Wilson
2019-08-17 14:47 ` [PATCH 4/6] dma-fence: Avoid list_del during fence->cb_list iteration Chris Wilson
2019-08-17 14:47 ` [PATCH 5/6] dma-fence: Simply wrap dma_fence_signal_locked with dma_fence_signal Chris Wilson
2019-08-17 15:16   ` Koenig, Christian
2019-08-17 15:23   ` [PATCH v3] " Chris Wilson
2019-08-17 15:25     ` Koenig, Christian
2019-08-17 14:47 ` [PATCH 6/6] dma-fence: Store the timestamp in the same union as the cb_list Chris Wilson
2019-08-17 15:20   ` Koenig, Christian
2019-08-17 15:27     ` Chris Wilson
2019-08-17 15:31       ` Koenig, Christian
2019-08-17 15:30   ` [PATCH v2] " Chris Wilson
2019-08-17 15:40     ` Koenig, Christian [this message]
2019-08-17 15:30 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] dma-buf: Introduce selftesting framework (rev2) Patchwork
2019-08-17 15:53 ` ✓ Fi.CI.BAT: success " Patchwork
2019-08-17 15:56 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [1/6] dma-buf: Introduce selftesting framework (rev3) Patchwork
2019-08-17 16:18 ` ✓ Fi.CI.BAT: success " Patchwork
2019-08-18  9:08 ` ✗ Fi.CI.IGT: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b8479897-2543-d965-004b-d46b7fc2ea39@amd.com \
    --to=christian.koenig@amd.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.