We had two failure modes here:
1.
Deadlock in intelfb_alloc failure path where it calls
drm_framebuffer_remove, which grabs the struct mutex and intelfb_create
(caller of intelfb_alloc) was already holding it.
2.
Deadlock in intelfb_create failure path where it calls
drm_framebuffer_unreference, which grabs the struct mutex and
intelfb_create was already holding it.
[Daniel Vetter on why struct_mutex needs to be locked in the second half
of intelfb_create: "The vma [for the fbdev] is pinned, the problem is
that we re-lookup it a few times, which is racy. We should instead track
the vma directly, but oh well we don't."]
v2:
* Reformat commit msg to 72 chars. (Lukas Wunner)
* Add third failure mode. (Lukas Wunner)
v5:
* Rebase on drm-intel-nightly 2015y-09m-01d-09h-06m-08s UTC,
rephrase commit message. (Jani Nicula)
v6:
* In intelfb_alloc, if __intel_framebuffer_create failed,
fb will be an ERR_PTR, thus not null. So in the failure
path we need to check for IS_ERR_OR_NULL to avoid calling
drm_framebuffer_remove on the ERR_PTR. (Lukas Wunner)
* Since this is init code a drm_framebuffer_unreference should
be all we need. drm_framebuffer_remove is for framebuffers
that userspace has created - and is getting somewhat
defeatured. (Daniel Vetter)
v7:
* Clarify why struct_mutex needs to be locked in the second half
of intelfb_create. (Daniel Vetter)
Fixes: 60a5ca015ffd ("drm/i915: Add locking around
framebuffer_references--")
Reported-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
[Lukas: Create v3 + v4 + v5 + v6 + v7 based on Tvrtko's v2]
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/47d4e88c91b3bf0f7a280cabec54c8c8cf0cf6f2.1446892879.git.lukas@wunner.de
Signed-off-by: Jani Nikula <jani.nikula@intel.com>