[Intel-gfx] [CI 2/5] drm/i915/breadcrumbs: Update bottom-half before marking as complete

Chris Wilson chris at chris-wilson.co.uk
Wed Mar 15 20:49:18 UTC 2017


On Wed, Mar 15, 2017 at 08:38:07PM +0000, Chris Wilson wrote:
> When adding a new request to the breadcrumb rbtree, we mark all those
> requests inside the rbtree that are already completed as complete. This
> wakes those waiters up and allows them to skip the spinlock before
> returning to userspace. If one of those is the current bottom-half and
> allocated its intel_wait on the stack, it may then overwrite the
> b->irq_wait upon exiting i915_wait_request() just as the interrupt handler
> dereferences it.
> 
> Fixes: 56299fb7d904 ("drm/i915: Signal first fence from irq handler if complete")
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Mika Kuoppala <mika.kuoppala at linux.intel.com>
> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_breadcrumbs.c | 36 +++++++++++++++++---------------
>  1 file changed, 19 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> index 3f222dee4c25..f50cb1e7e145 100644
> --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c
> +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c
> @@ -303,6 +303,7 @@ static inline void __intel_breadcrumbs_next(struct intel_engine_cs *engine,
>  
>  	spin_lock(&b->irq_lock);
>  	GEM_BUG_ON(!b->irq_armed);
> +	GEM_BUG_ON(!b->irq_wait);
>  	b->irq_wait = to_wait(next);
>  	spin_unlock(&b->irq_lock);
>  
> @@ -378,25 +379,10 @@ static bool __intel_engine_add_wait(struct intel_engine_cs *engine,
>  	rb_link_node(&wait->node, parent, p);
>  	rb_insert_color(&wait->node, &b->waiters);
>  
> -	if (completed) {
> -		struct rb_node *next = rb_next(completed);
> -
> -		GEM_BUG_ON(!next && !first);
> -		if (next && next != &wait->node) {
> -			GEM_BUG_ON(first);
> -			__intel_breadcrumbs_next(engine, next);
> -		}
> -
> -		do {
> -			struct intel_wait *crumb = to_wait(completed);
> -			completed = rb_prev(completed);
> -			__intel_breadcrumbs_finish(b, crumb);
> -		} while (completed);
> -	}
> -
>  	if (first) {
> -		spin_lock(&b->irq_lock);
>  		GEM_BUG_ON(rb_first(&b->waiters) != &wait->node);

Rebase error! :(
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre


More information about the Intel-gfx mailing list