]> git.baikalelectronics.ru Git - kernel.git/commit
drm/i915: Tighten atomicity of i915_active_acquire vs i915_active_release
authorChris Wilson <chris@chris-wilson.co.uk>
Sun, 26 Jan 2020 10:23:43 +0000 (10:23 +0000)
committerJani Nikula <jani.nikula@intel.com>
Wed, 12 Feb 2020 11:24:44 +0000 (13:24 +0200)
commit8342f9e84ae14748b5753820d1e4331b08b9284a
treed1c1825c85e5e2abe3f12c35da6a2eaee7c9bfee
parent0fa50a6c843cb8bd2a4f84bde14f4b9ad08f9898
drm/i915: Tighten atomicity of i915_active_acquire vs i915_active_release

As we use a mutex to serialise the first acquire (as it may be a lengthy
operation), but only an atomic decrement for the release, we have to
be careful in case a second thread races and completes both
acquire/release as the first finishes its acquire.

Thread A Thread B
i915_active_acquire i915_active_acquire
  atomic_read() == 0   atomic_read() == 0
  mutex_lock()   mutex_lock()
  atomic_read() == 0
    ref->active();
  atomic_inc()
  mutex_unlock()
  atomic_read() == 1
i915_active_release
  atomic_dec_and_test() -> 0
    ref->retire()
  atomic_inc() -> 1
  mutex_unlock()

So thread A has acquired the ref->active_count but since the ref was
still active at the time, it did not initialise it. By switching the
check inside the mutex to an atomic increment only if already active, we
close the race.

Fixes: 95f1a207a4f1 ("drm/i915: Split i915_active.mutex into an irq-safe spinlock for the rbtree")
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200126102346.1877661-3-chris@chris-wilson.co.uk
(cherry picked from commit ac0e331a628b5ded087eab09fad2ffb082ac61ba)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/i915_active.c