VIGS: Introduce an idr to generate surface ids
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Fri, 26 Apr 2013 06:08:48 +0000 (10:08 +0400)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 9 Apr 2014 05:42:20 +0000 (14:42 +0900)
Using mmap offsets as surface ids is not good since they're 64-bit

Change-Id: I03356f4f5de67153d87cdb73e4c0102b67883793

drivers/gpu/drm/vigs/vigs_comm.c
drivers/gpu/drm/vigs/vigs_crtc.c
drivers/gpu/drm/vigs/vigs_device.c
drivers/gpu/drm/vigs/vigs_device.h
drivers/gpu/drm/vigs/vigs_protocol.h
drivers/gpu/drm/vigs/vigs_surface.c
drivers/gpu/drm/vigs/vigs_surface.h
include/drm/vigs_drm.h

index 428067df7bc27fe2fe62e55ea54d81f4f38e519a..f6604fba138a028eff9d43f1e1073bffa73f9246 100644 (file)
@@ -237,7 +237,7 @@ int vigs_comm_create_surface(struct vigs_comm *comm,
     int ret;
     struct vigsp_cmd_create_surface_request *request;
 
-    DRM_DEBUG_DRIVER("width = %u, height = %u, stride = %u, fmt = %d, id = 0x%llX\n",
+    DRM_DEBUG_DRIVER("width = %u, height = %u, stride = %u, fmt = %d, id = %u\n",
                      width,
                      height,
                      stride,
@@ -269,7 +269,7 @@ int vigs_comm_destroy_surface(struct vigs_comm *comm, vigsp_surface_id id)
     int ret;
     struct vigsp_cmd_destroy_surface_request *request;
 
-    DRM_DEBUG_DRIVER("id = 0x%llX\n", id);
+    DRM_DEBUG_DRIVER("id = %u\n", id);
 
     ret = vigs_comm_prepare(comm,
                             vigsp_cmd_destroy_surface,
@@ -294,7 +294,7 @@ int vigs_comm_set_root_surface(struct vigs_comm *comm,
     int ret;
     struct vigsp_cmd_set_root_surface_request *request;
 
-    DRM_DEBUG_DRIVER("id = 0x%llX\n", id);
+    DRM_DEBUG_DRIVER("id = %u, offset = %u\n", id, offset);
 
     ret = vigs_comm_prepare(comm,
                             vigsp_cmd_set_root_surface,
index 1be92815e612784b2462ca60fefc9fd4859e239a..7fcfbdfa0c2cf3691b9f679463724294f5ac8076 100644 (file)
@@ -68,7 +68,7 @@ static int vigs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
     }
 
     ret = vigs_comm_set_root_surface(vigs_dev->comm,
-                                     vigs_surface_id(vigs_fb->fb_sfc),
+                                     vigs_fb->fb_sfc->id,
                                      vigs_gem_offset(&vigs_fb->fb_sfc->gem));
 
     if (ret != 0) {
index 602b66f512c4572a85b51340a608b9f6ff454c42..e71dc4093195504e9990b52e1c85b62f4a28f04b 100644 (file)
@@ -6,6 +6,7 @@
 #include "vigs_comm.h"
 #include "vigs_fbdev.h"
 #include "vigs_execbuffer.h"
+#include "vigs_surface.h"
 #include <drm/vigs_drm.h>
 
 int vigs_device_init(struct vigs_device *vigs_dev,
@@ -30,6 +31,8 @@ int vigs_device_init(struct vigs_device *vigs_dev,
     vigs_dev->io_base = pci_resource_start(pci_dev, 2);
     vigs_dev->io_size = pci_resource_len(pci_dev, 2);
 
+    idr_init(&vigs_dev->surface_idr);
+
     if (!vigs_dev->vram_base || !vigs_dev->ram_base || !vigs_dev->io_base) {
         DRM_ERROR("VRAM, RAM or IO bar not found on device\n");
         ret = -ENODEV;
@@ -99,6 +102,7 @@ fail3:
 fail2:
     drm_rmmap(vigs_dev->drm_dev, vigs_dev->io_map);
 fail1:
+    idr_destroy(&vigs_dev->surface_idr);
 
     return ret;
 }
@@ -112,6 +116,7 @@ void vigs_device_cleanup(struct vigs_device *vigs_dev)
     vigs_comm_destroy(vigs_dev->comm);
     vigs_mman_destroy(vigs_dev->mman);
     drm_rmmap(vigs_dev->drm_dev, vigs_dev->io_map);
+    idr_destroy(&vigs_dev->surface_idr);
 }
 
 int vigs_device_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -127,6 +132,71 @@ int vigs_device_mmap(struct file *filp, struct vm_area_struct *vma)
     return vigs_mman_mmap(vigs_dev->mman, filp, vma);
 }
 
+int vigs_device_add_surface(struct vigs_device *vigs_dev,
+                            struct vigs_surface *sfc,
+                            vigsp_surface_id* id)
+{
+    int ret, tmp_id = 0;
+
+    do {
+        if (unlikely(idr_pre_get(&vigs_dev->surface_idr, GFP_KERNEL) == 0)) {
+            return -ENOMEM;
+        }
+
+        ret = idr_get_new_above(&vigs_dev->surface_idr, sfc, 1, &tmp_id);
+    } while (ret == -EAGAIN);
+
+    *id = tmp_id;
+
+    return ret;
+}
+
+void vigs_device_remove_surface(struct vigs_device *vigs_dev,
+                                vigsp_surface_id sfc_id)
+{
+    idr_remove(&vigs_dev->surface_idr, sfc_id);
+}
+
+int vigs_device_add_surface_unlocked(struct vigs_device *vigs_dev,
+                                     struct vigs_surface *sfc,
+                                     vigsp_surface_id* id)
+{
+    int ret;
+
+    mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+    ret = vigs_device_add_surface(vigs_dev, sfc, id);
+    mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+
+    return ret;
+}
+
+struct vigs_surface
+    *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;
+}
+
+void vigs_device_remove_surface_unlocked(struct vigs_device *vigs_dev,
+                                         vigsp_surface_id sfc_id)
+{
+    mutex_lock(&vigs_dev->drm_dev->struct_mutex);
+    vigs_device_remove_surface(vigs_dev, sfc_id);
+    mutex_unlock(&vigs_dev->drm_dev->struct_mutex);
+}
+
 int vigs_device_exec_ioctl(struct drm_device *drm_dev,
                            void *data,
                            struct drm_file *file_priv)
index d44ab5452fb7fc10d3c84cf4317f06b7f3ceb86f..63d0684e1e79bd30fc3bbd5c1253aef4fb1ef694 100644 (file)
@@ -2,10 +2,12 @@
 #define _VIGS_DEVICE_H_
 
 #include "drmP.h"
+#include "vigs_protocol.h"
 
 struct vigs_mman;
 struct vigs_comm;
 struct vigs_fbdev;
+struct vigs_surface;
 
 struct vigs_device
 {
@@ -22,6 +24,8 @@ struct vigs_device
     resource_size_t io_base;
     resource_size_t io_size;
 
+    struct idr surface_idr;
+
     /* Map of IO BAR. */
     drm_local_map_t *io_map;
 
@@ -41,6 +45,31 @@ void vigs_device_cleanup(struct vigs_device *vigs_dev);
 
 int vigs_device_mmap(struct file *filp, struct vm_area_struct *vma);
 
+/*
+ * Must be called with drm_device::struct_mutex held.
+ * @{
+ */
+int vigs_device_add_surface(struct vigs_device *vigs_dev,
+                            struct vigs_surface *sfc,
+                            vigsp_surface_id* id);
+
+void vigs_device_remove_surface(struct vigs_device *vigs_dev,
+                                vigsp_surface_id sfc_id);
+/*
+ * @}
+ */
+
+int vigs_device_add_surface_unlocked(struct vigs_device *vigs_dev,
+                                     struct vigs_surface *sfc,
+                                     vigsp_surface_id* id);
+
+struct vigs_surface
+    *vigs_device_reference_surface_unlocked(struct vigs_device *vigs_dev,
+                                            vigsp_surface_id sfc_id);
+
+void vigs_device_remove_surface_unlocked(struct vigs_device *vigs_dev,
+                                         vigsp_surface_id sfc_id);
+
 /*
  * IOCTLs
  * @{
index 5a3e6dc8051af036c6671f3d299393509ba98f31..739490d40d4880c65ec8be8ffc3c8e6d1b69bcb0 100644 (file)
@@ -26,7 +26,7 @@ typedef unsigned int vigsp_u32;
 typedef unsigned long long vigsp_u64;
 
 typedef vigsp_u32 vigsp_bool;
-typedef vigsp_u64 vigsp_surface_id;
+typedef vigsp_u32 vigsp_surface_id;
 typedef vigsp_u32 vigsp_offset;
 typedef vigsp_u32 vigsp_color;
 typedef vigsp_u64 vigsp_va;
index 2438debe706011cf7c6fcba3b3ca2e45c9ec708b..a4fa688ce3412ed3507d73a7b91d3cd087b7c68f 100644 (file)
@@ -8,8 +8,9 @@ static void vigs_surface_destroy(struct vigs_gem_object *gem)
     struct vigs_surface *sfc = vigs_gem_to_vigs_surface(gem);
     struct vigs_device *vigs_dev = gem->base.dev->dev_private;
 
-    vigs_comm_destroy_surface(vigs_dev->comm,
-                              vigs_surface_id(sfc));
+    vigs_comm_destroy_surface(vigs_dev->comm, sfc->id);
+
+    vigs_device_remove_surface(vigs_dev, sfc->id);
 
     vigs_gem_cleanup(&sfc->gem);
 }
@@ -46,19 +47,27 @@ int vigs_surface_create(struct vigs_device *vigs_dev,
         goto fail1;
     }
 
+    ret = vigs_device_add_surface_unlocked(vigs_dev, *sfc, &(*sfc)->id);
+
+    if (ret != 0) {
+        goto fail2;
+    }
+
     ret = vigs_comm_create_surface(vigs_dev->comm,
                                    width,
                                    height,
                                    stride,
                                    format,
-                                   vigs_surface_id(*sfc));
+                                   (*sfc)->id);
 
     if (ret != 0) {
-        goto fail2;
+        goto fail3;
     }
 
     return 0;
 
+fail3:
+    vigs_device_remove_surface_unlocked(vigs_dev, (*sfc)->id);
 fail2:
     vigs_gem_cleanup(&(*sfc)->gem);
 fail1:
@@ -97,7 +106,7 @@ int vigs_surface_create_ioctl(struct drm_device *drm_dev,
     if (ret == 0) {
         args->handle = handle;
         args->mmap_offset = vigs_gem_mmap_offset(&sfc->gem);
-        args->id = vigs_surface_id(sfc);
+        args->id = sfc->id;
     }
 
     return ret;
@@ -131,7 +140,7 @@ int vigs_surface_info_ioctl(struct drm_device *drm_dev,
     args->stride = sfc->stride;
     args->format = sfc->format;
     args->mmap_offset = vigs_gem_mmap_offset(vigs_gem);
-    args->id = vigs_surface_id(sfc);
+    args->id = sfc->id;
 
     drm_gem_object_unreference_unlocked(gem);
 
index aa00c00a5355da0a5156472478e2d8e95de88d3a..8b904f82b7ff011c94d1fc0d66072b33e883f7fa 100644 (file)
@@ -16,6 +16,7 @@ struct vigs_surface
     u32 height;
     u32 stride;
     vigsp_surface_format format;
+    vigsp_surface_id id;
 };
 
 static inline struct vigs_surface *vigs_gem_to_vigs_surface(struct vigs_gem_object *vigs_gem)
@@ -30,11 +31,6 @@ int vigs_surface_create(struct vigs_device *vigs_dev,
                         vigsp_surface_format format,
                         struct vigs_surface **sfc);
 
-static inline vigsp_surface_id vigs_surface_id(struct vigs_surface *sfc)
-{
-    return vigs_gem_mmap_offset(&sfc->gem);
-}
-
 /*
  * IOCTLs
  * @{
index b64553c3dc3da62344f3fdcbcd8f6a240f78c181..56676cb31aaf1dc5945a10ea1fbd9f83c61ff6c3 100644 (file)
@@ -23,7 +23,7 @@ struct drm_vigs_create_surface
     uint32_t format;
     uint32_t handle;
     uint64_t mmap_offset;
-    uint64_t id;
+    uint32_t id;
 };
 
 struct drm_vigs_create_execbuffer
@@ -40,7 +40,7 @@ struct drm_vigs_surface_info
     uint32_t stride;
     uint32_t format;
     uint64_t mmap_offset;
-    uint64_t id;
+    uint32_t id;
 };
 
 struct drm_vigs_exec