VIGS: Potential deadlock fixed
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Tue, 30 Apr 2013 13:10:46 +0000 (17:10 +0400)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 9 Apr 2014 05:42:21 +0000 (14:42 +0900)
Change-Id: I6e7bfc824fc637bcc77896919c504da17eddfe2b

drivers/gpu/drm/vigs/vigs_device.c

index aabead480eb5ebb738d1f3bec511d062c8b409b4..c1a027fecfbd34938067453727b080d2d865ebae 100644 (file)
@@ -9,21 +9,22 @@
 #include "vigs_surface.h"
 #include <drm/vigs_drm.h>
 
-/*
- * Must be called with drm_device::struct_mutex held.
- */
 static struct vigs_surface
-    *vigs_device_reference_surface(struct vigs_device *vigs_dev,
-                                   vigsp_surface_id sfc_id)
+    *vigs_device_reference_surface_unlocked(struct vigs_device *vigs_dev,
+                                            vigsp_surface_id sfc_id)
 {
     struct vigs_surface *sfc;
 
+    mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+
     sfc = idr_find(&vigs_dev->surface_idr, sfc_id);
 
     if (sfc) {
         drm_gem_object_reference(&sfc->gem.base);
     }
 
+    mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+
     return sfc;
 }
 
@@ -45,8 +46,6 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev,
     struct vigs_surface *sfc;
     int ret = 0;
 
-    mutex_lock(&vigs_dev->drm_dev->struct_mutex);
-
     /*
      * GEM is always at least PAGE_SIZE long, so don't check
      * if batch header is out of bounds.
@@ -71,7 +70,7 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev,
         case vigsp_cmd_update_vram:
             update_vram_request =
                 (struct vigsp_cmd_update_vram_request*)(request_header + 1);
-            sfc = vigs_device_reference_surface(vigs_dev, update_vram_request->sfc_id);
+            sfc = vigs_device_reference_surface_unlocked(vigs_dev, update_vram_request->sfc_id);
             if (!sfc) {
                 DRM_ERROR("Surface %u not found\n", update_vram_request->sfc_id);
                 ret = -EINVAL;
@@ -88,7 +87,7 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev,
         case vigsp_cmd_update_gpu:
             update_gpu_request =
                 (struct vigsp_cmd_update_gpu_request*)(request_header + 1);
-            sfc = vigs_device_reference_surface(vigs_dev, update_gpu_request->sfc_id);
+            sfc = vigs_device_reference_surface_unlocked(vigs_dev, update_gpu_request->sfc_id);
             if (!sfc) {
                 DRM_ERROR("Surface %u not found\n", update_gpu_request->sfc_id);
                 ret = -EINVAL;
@@ -111,8 +110,6 @@ static int vigs_device_patch_commands(struct vigs_device *vigs_dev,
             request_header->size);
     }
 
-    mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
-
     return 0;
 }