From: Stanislav Vorobiov Date: Fri, 26 Apr 2013 06:08:48 +0000 (+0400) Subject: VIGS: Introduce an idr to generate surface ids X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=efa9adf5b6769a228f78ada6c3f1d526e91ba566;p=sdk%2Femulator%2Femulator-kernel.git VIGS: Introduce an idr to generate surface ids Using mmap offsets as surface ids is not good since they're 64-bit --- diff --git a/drivers/gpu/drm/vigs/vigs_comm.c b/drivers/gpu/drm/vigs/vigs_comm.c index 428067df7bc2..f6604fba138a 100644 --- a/drivers/gpu/drm/vigs/vigs_comm.c +++ b/drivers/gpu/drm/vigs/vigs_comm.c @@ -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, diff --git a/drivers/gpu/drm/vigs/vigs_crtc.c b/drivers/gpu/drm/vigs/vigs_crtc.c index 1be92815e612..7fcfbdfa0c2c 100644 --- a/drivers/gpu/drm/vigs/vigs_crtc.c +++ b/drivers/gpu/drm/vigs/vigs_crtc.c @@ -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) { diff --git a/drivers/gpu/drm/vigs/vigs_device.c b/drivers/gpu/drm/vigs/vigs_device.c index 602b66f512c4..e71dc4093195 100644 --- a/drivers/gpu/drm/vigs/vigs_device.c +++ b/drivers/gpu/drm/vigs/vigs_device.c @@ -6,6 +6,7 @@ #include "vigs_comm.h" #include "vigs_fbdev.h" #include "vigs_execbuffer.h" +#include "vigs_surface.h" #include 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) diff --git a/drivers/gpu/drm/vigs/vigs_device.h b/drivers/gpu/drm/vigs/vigs_device.h index d44ab5452fb7..63d0684e1e79 100644 --- a/drivers/gpu/drm/vigs/vigs_device.h +++ b/drivers/gpu/drm/vigs/vigs_device.h @@ -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 * @{ diff --git a/drivers/gpu/drm/vigs/vigs_protocol.h b/drivers/gpu/drm/vigs/vigs_protocol.h index 5a3e6dc8051a..739490d40d48 100644 --- a/drivers/gpu/drm/vigs/vigs_protocol.h +++ b/drivers/gpu/drm/vigs/vigs_protocol.h @@ -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; diff --git a/drivers/gpu/drm/vigs/vigs_surface.c b/drivers/gpu/drm/vigs/vigs_surface.c index 2438debe7060..a4fa688ce341 100644 --- a/drivers/gpu/drm/vigs/vigs_surface.c +++ b/drivers/gpu/drm/vigs/vigs_surface.c @@ -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); diff --git a/drivers/gpu/drm/vigs/vigs_surface.h b/drivers/gpu/drm/vigs/vigs_surface.h index aa00c00a5355..8b904f82b7ff 100644 --- a/drivers/gpu/drm/vigs/vigs_surface.h +++ b/drivers/gpu/drm/vigs/vigs_surface.h @@ -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 * @{ diff --git a/include/drm/vigs_drm.h b/include/drm/vigs_drm.h index b64553c3dc3d..56676cb31aaf 100644 --- a/include/drm/vigs_drm.h +++ b/include/drm/vigs_drm.h @@ -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