drm/vmwgfx: Fix an overlay lockdep error
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 25 Jun 2015 19:00:39 +0000 (12:00 -0700)
committerThomas Hellstrom <thellstrom@vmware.com>
Wed, 5 Aug 2015 12:01:05 +0000 (14:01 +0200)
Fix a circular locking dependency between
struct vmw_overlay::mutex and
struct vmw_private::reservation_sem

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_resource.c

index 210ef15b1d0919c59e8d7eb8aff72b588f2f6ea6..3fd80701771a0a9e8215b84b170c5cdf80f09fb1 100644 (file)
@@ -900,20 +900,21 @@ int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
        ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
                                   vmw_user_stream_size,
                                   false, true);
+       ttm_read_unlock(&dev_priv->reservation_sem);
        if (unlikely(ret != 0)) {
                if (ret != -ERESTARTSYS)
                        DRM_ERROR("Out of graphics memory for stream"
                                  " creation.\n");
-               goto out_unlock;
-       }
 
+               goto out_ret;
+       }
 
        stream = kmalloc(sizeof(*stream), GFP_KERNEL);
        if (unlikely(stream == NULL)) {
                ttm_mem_global_free(vmw_mem_glob(dev_priv),
                                    vmw_user_stream_size);
                ret = -ENOMEM;
-               goto out_unlock;
+               goto out_ret;
        }
 
        res = &stream->stream.res;
@@ -926,7 +927,7 @@ int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
 
        ret = vmw_stream_init(dev_priv, &stream->stream, vmw_user_stream_free);
        if (unlikely(ret != 0))
-               goto out_unlock;
+               goto out_ret;
 
        tmp = vmw_resource_reference(res);
        ret = ttm_base_object_init(tfile, &stream->base, false, VMW_RES_STREAM,
@@ -940,8 +941,7 @@ int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
        arg->stream_id = res->id;
 out_err:
        vmw_resource_unreference(&res);
-out_unlock:
-       ttm_read_unlock(&dev_priv->reservation_sem);
+out_ret:
        return ret;
 }