drm/i915: GEM operations need to be done under the big lock
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>
Thu, 11 Feb 2016 10:27:29 +0000 (10:27 +0000)
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>
Mon, 15 Feb 2016 16:10:18 +0000 (16:10 +0000)
VMA creation and GEM list management need the big lock.

v2:

Mutex unlock ended on the wrong path somehow. (0-day, Julia Lawall)

Not to mention drm_gem_object_unreference was there in existing
code with no mutex held.

v3:

Some callers of i915_gem_object_create_stolen_for_preallocated
already hold the lock so move the mutex into the other caller
as well.

v4:

Changed to lockdep_assert_held. (Chris Wilson)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_gem_stolen.c
drivers/gpu/drm/i915/intel_display.c

index ba1a00d815d30587570587df8f4e0da630da9417..feec0f80d8ef1ce82b15e929cb774a3d1c21d01a 100644 (file)
@@ -638,6 +638,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
        if (!drm_mm_initialized(&dev_priv->mm.stolen))
                return NULL;
 
+       lockdep_assert_held(&dev->struct_mutex);
+
        DRM_DEBUG_KMS("creating preallocated stolen object: stolen_offset=%x, gtt_offset=%x, size=%x\n",
                        stolen_offset, gtt_offset, size);
 
index a18bd1296ce8844e6fc2375e5b0d49e671369ff9..0811dd136c5613d606bc23583a5b8b270bbf55c9 100644 (file)
@@ -2551,12 +2551,16 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        if (size_aligned * 2 > dev_priv->gtt.stolen_usable_size)
                return false;
 
+       mutex_lock(&dev->struct_mutex);
+
        obj = i915_gem_object_create_stolen_for_preallocated(dev,
                                                             base_aligned,
                                                             base_aligned,
                                                             size_aligned);
-       if (!obj)
+       if (!obj) {
+               mutex_unlock(&dev->struct_mutex);
                return false;
+       }
 
        obj->tiling_mode = plane_config->tiling;
        if (obj->tiling_mode == I915_TILING_X)
@@ -2569,12 +2573,12 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        mode_cmd.modifier[0] = fb->modifier[0];
        mode_cmd.flags = DRM_MODE_FB_MODIFIERS;
 
-       mutex_lock(&dev->struct_mutex);
        if (intel_framebuffer_init(dev, to_intel_framebuffer(fb),
                                   &mode_cmd, obj)) {
                DRM_DEBUG_KMS("intel fb init failed\n");
                goto out_unref_obj;
        }
+
        mutex_unlock(&dev->struct_mutex);
 
        DRM_DEBUG_KMS("initial plane fb obj %p\n", obj);