]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/gpu/drm/i915/intel_display.c
drm/i915: lock correct mutex around object unreference.
[linux-2.6-omap-h63xx.git] / drivers / gpu / drm / i915 / intel_display.c
index 114a7a1a8740096217b62d5fc108210c3cc8f44d..31c3732b7a690aa7d813f4ecad46a071a7ef684f 100644 (file)
@@ -1016,8 +1016,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 
        if (bo->size < width * height * 4) {
                DRM_ERROR("buffer is to small\n");
-               drm_gem_object_unreference(bo);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto fail;
        }
 
        /* we only need to pin inside GTT if cursor is non-phy */
@@ -1025,16 +1025,14 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                ret = i915_gem_object_pin(bo, PAGE_SIZE);
                if (ret) {
                        DRM_ERROR("failed to pin cursor bo\n");
-                       drm_gem_object_unreference(bo);
-                       return ret;
+                       goto fail;
                }
                addr = obj_priv->gtt_offset;
        } else {
                ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
                if (ret) {
                        DRM_ERROR("failed to attach phys object\n");
-                       drm_gem_object_unreference(bo);
-                       return ret;
+                       goto fail;
                }
                addr = obj_priv->phys_obj->handle->busaddr;
        }
@@ -1054,13 +1052,20 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                                i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
                } else
                        i915_gem_object_unpin(intel_crtc->cursor_bo);
+               mutex_lock(&dev->struct_mutex);
                drm_gem_object_unreference(intel_crtc->cursor_bo);
+               mutex_unlock(&dev->struct_mutex);
        }
 
        intel_crtc->cursor_addr = addr;
        intel_crtc->cursor_bo = bo;
 
        return 0;
+fail:
+       mutex_lock(&dev->struct_mutex);
+       drm_gem_object_unreference(bo);
+       mutex_unlock(&dev->struct_mutex);
+       return ret;
 }
 
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)