Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Fix oopses in the overlay code due to i915_gem_active stuff

The i915_gem_active stuff doesn't like a NULL ->retire hook, but
the overlay code can set it to NULL. That obviously ends up oopsing.
Fix it by introducing a new helper to assign the retirement callback
that will switch out the NULL function pointer with
i915_gem_retire_noop.

Cc: stable@vger.kernel.org
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Fixes: 0d9bdd886f29 ("drm/i915: Convert intel_overlay to request tracking")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20161207175647.10018-1-chris@chris-wilson.co.uk
(cherry picked from commit ecd9caa0522db5a6b03ac8858c42067ef9d8323b)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

authored by

Ville Syrjälä and committed by
Jani Nikula
b72eb5ff a6d3e7d3

+21 -1
+19
drivers/gpu/drm/i915/i915_gem_request.h
··· 413 413 rcu_assign_pointer(active->request, request); 414 414 } 415 415 416 + /** 417 + * i915_gem_active_set_retire_fn - updates the retirement callback 418 + * @active - the active tracker 419 + * @fn - the routine called when the request is retired 420 + * @mutex - struct_mutex used to guard retirements 421 + * 422 + * i915_gem_active_set_retire_fn() updates the function pointer that 423 + * is called when the final request associated with the @active tracker 424 + * is retired. 425 + */ 426 + static inline void 427 + i915_gem_active_set_retire_fn(struct i915_gem_active *active, 428 + i915_gem_retire_fn fn, 429 + struct mutex *mutex) 430 + { 431 + lockdep_assert_held(mutex); 432 + active->retire = fn ?: i915_gem_retire_noop; 433 + } 434 + 416 435 static inline struct drm_i915_gem_request * 417 436 __i915_gem_active_peek(const struct i915_gem_active *active) 418 437 {
+2 -1
drivers/gpu/drm/i915/intel_overlay.c
··· 216 216 { 217 217 GEM_BUG_ON(i915_gem_active_peek(&overlay->last_flip, 218 218 &overlay->i915->drm.struct_mutex)); 219 - overlay->last_flip.retire = retire; 219 + i915_gem_active_set_retire_fn(&overlay->last_flip, retire, 220 + &overlay->i915->drm.struct_mutex); 220 221 i915_gem_active_set(&overlay->last_flip, req); 221 222 i915_add_request(req); 222 223 }