drm/i915: lock correct mutex around object unreference.
authorDave Airlie <airlied@linux.ie>
Thu, 15 Jan 2009 04:03:07 +0000 (14:03 +1000)
committerDave Airlie <airlied@linux.ie>
Fri, 16 Jan 2009 08:45:22 +0000 (18:45 +1000)
This makes sure the mutex is held around the unreference.

Signed-off-by: Dave Airlie <airlied@redhat.com>
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)