OSDN Git Service

drm/i915: Don't disable interrupts for intel_engine_breadcrumbs_irq()
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Thu, 26 Sep 2019 10:56:43 +0000 (12:56 +0200)
committerChris Wilson <chris@chris-wilson.co.uk>
Thu, 26 Sep 2019 17:44:35 +0000 (18:44 +0100)
commite3792238c1dde5059e44e0f14899497ac875443d
tree76f6c1699de62c8e055d0ef318e1a1067511aa88
parent132dfc78d3eb51b6fc8e667183b3572d41e3fe9f
drm/i915: Don't disable interrupts for intel_engine_breadcrumbs_irq()

The function intel_engine_breadcrumbs_irq() is always invoked from an interrupt
handler and for that reason it invokes (as an optimisation) only spin_lock()
for locking assuming that the interrupts are already disabled. The
function intel_engine_signal_breadcrumbs() is provided to disable
interrupts while the former function is invoked so that assumption is
also true for callers from preemptible context.

On PREEMPT_RT local_irq_disable() really disables interrupts and this
forbids to invoke spin_lock() which becomes a sleeping spinlock.

This is also problematic with `threadirqs' in conjunction with
irq_work. With force threading the interrupt handler, the handler is
invoked with disabled BH but with interrupts enabled. This is okay and
the lock itself is never acquired in IRQ context. This changes with
irq_work (signal_irq_work()) which _still_ invokes
intel_engine_breadcrumbs_irq() from IRQ context. Lockdep should see this
and complain.

Acquire the locks in intel_engine_breadcrumbs_irq() with _irqsave()
suffix and let all callers invoke intel_engine_breadcrumbs_irq()
directly instead using intel_engine_signal_breadcrumbs().

Reported-by: Clark Williams <williams@redhat.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20190926105644.16703-2-bigeasy@linutronix.de
drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
drivers/gpu/drm/i915/gt/intel_engine.h
drivers/gpu/drm/i915/gt/intel_hangcheck.c
drivers/gpu/drm/i915/gt/intel_reset.c