From 604215396847a7964fd7d68aa89d4f778b3bf22b Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 5 Sep 2006 18:00:25 +0200 Subject: [PATCH] Fence all unfenced buffers function. --- libdrm/xf86drm.c | 15 ++++++++ libdrm/xf86drm.h | 1 + linux-core/drmP.h | 14 ++++++-- linux-core/drm_bo.c | 33 ++++++++--------- linux-core/drm_fence.c | 96 +++++++++++++++++++++++++++++++------------------- shared-core/drm.h | 3 +- 6 files changed, 105 insertions(+), 57 deletions(-) diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 068d0fb..6d08742 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -2259,6 +2259,21 @@ int drmFenceCreate(int fd, int shareable, int class,unsigned type, fence->signaled = 0; return 0; } + +int drmFenceBuffers(int fd, int shareable, drmFence *fence) +{ + drm_fence_arg_t arg; + + arg.flags = (shareable) ? DRM_FENCE_FLAG_SHAREABLE : 0; + arg.op = drm_fence_buffers; + if (ioctl(fd, DRM_IOCTL_FENCE, &arg)) + return -errno; + fence->handle = arg.handle; + fence->class = arg.class; + fence->type = arg.type; + fence->signaled = 0; + return 0; +} int drmFenceDestroy(int fd, const drmFence *fence) { diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h index f257ded..be1eeef 100644 --- a/libdrm/xf86drm.h +++ b/libdrm/xf86drm.h @@ -626,6 +626,7 @@ extern int drmFenceSignaled(int fd, drmFence *fence); extern int drmFenceWait(int fd, drmFence *fence, unsigned flush_type, int lazy, int ignore_signals); extern int drmFenceEmit(int fd, drmFence *fence, unsigned emit_type); +extern int drmFenceBuffers(int fd, int shareable, drmFence *fence); /* TTMS */ extern int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, diff --git a/linux-core/drmP.h b/linux-core/drmP.h index 2376637..7de7422 100644 --- a/linux-core/drmP.h +++ b/linux-core/drmP.h @@ -1379,10 +1379,16 @@ extern void drm_fence_usage_deref_locked(drm_device_t * dev, drm_fence_object_t * fence); extern void drm_fence_usage_deref_unlocked(drm_device_t * dev, drm_fence_object_t * fence); -extern int drm_fence_object_init(drm_device_t * dev, uint32_t type, int emit, - drm_fence_object_t * fence); extern int drm_fence_object_wait(drm_device_t * dev, drm_fence_object_t * fence, int lazy, int ignore_signals, uint32_t mask); +extern int drm_fence_object_create(drm_device_t *dev, uint32_t type, + int emit, drm_fence_object_t **c_fence); +extern int drm_fence_add_user_object(drm_file_t *priv, + drm_fence_object_t *fence, + int shareable); + + + extern int drm_fence_ioctl(DRM_IOCTL_ARGS); @@ -1394,6 +1400,10 @@ extern int drm_fence_ioctl(DRM_IOCTL_ARGS); extern int drm_bo_ioctl(DRM_IOCTL_ARGS); extern int drm_mm_init_ioctl(DRM_IOCTL_ARGS); extern int drm_bo_clean_mm(drm_device_t *dev); +extern int drm_fence_buffer_objects(drm_file_t * priv, + struct list_head *list, + drm_fence_object_t *fence, + drm_fence_object_t **used_fence); /* Inline replacements for DRM_IOREMAP macros */ diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c index 1f0bbba..68af5c3 100644 --- a/linux-core/drm_bo.c +++ b/linux-core/drm_bo.c @@ -199,8 +199,15 @@ void drm_bo_usage_deref_unlocked(drm_device_t * dev, drm_buffer_object_t * bo) } } +/* + * Note. The caller has to register (if applicable) + * and deregister fence object usage. + */ + int drm_fence_buffer_objects(drm_file_t * priv, - struct list_head *list, drm_fence_object_t * fence) + struct list_head *list, + drm_fence_object_t *fence, + drm_fence_object_t **used_fence) { drm_device_t *dev = priv->head->dev; drm_buffer_manager_t *bm = &dev->bm; @@ -230,19 +237,9 @@ int drm_fence_buffer_objects(drm_file_t * priv, goto out; } } else { - fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL); - - if (!fence) { - ret = -ENOMEM; - goto out; - } - - ret = drm_fence_object_init(dev, fence_flags, 1, fence); - - if (ret) { - kmem_cache_free(drm_cache.fence_object, fence); - goto out; - } + ret = drm_fence_object_create(dev, fence_flags, 1, &fence); + if (ret) + goto out; } /* @@ -285,14 +282,14 @@ int drm_fence_buffer_objects(drm_file_t * priv, drm_bo_usage_deref_locked(dev, entry); l = f_list.next; } - if (!count) - drm_fence_usage_deref_locked(dev, fence); - else if (count > 1) - atomic_add(count - 1, &fence->usage); + atomic_add(count, &fence->usage); out: mutex_unlock(&dev->struct_mutex); + *used_fence = fence; return ret; } +EXPORT_SYMBOL(drm_fence_buffer_objects); + /* * Call bo->mutex locked. diff --git a/linux-core/drm_fence.c b/linux-core/drm_fence.c index 1deeaaa..fd43d8b 100644 --- a/linux-core/drm_fence.c +++ b/linux-core/drm_fence.c @@ -417,14 +417,28 @@ int drm_fence_object_init(drm_device_t * dev, uint32_t type, int emit, EXPORT_SYMBOL(drm_fence_object_init); -static int drm_fence_object_create(drm_file_t * priv, uint32_t type, - int emit, int shareable, - uint32_t * user_handle, - drm_fence_object_t ** c_fence) +int drm_fence_add_user_object(drm_file_t *priv, drm_fence_object_t *fence, + int shareable) { drm_device_t *dev = priv->head->dev; int ret; + + mutex_lock(&dev->struct_mutex); + ret = drm_add_user_object(priv, &fence->base, shareable); + mutex_unlock(&dev->struct_mutex); + if (ret) + return ret; + fence->base.type = drm_fence_type; + fence->base.remove = &drm_fence_object_destroy; + return 0; +} +EXPORT_SYMBOL(drm_fence_add_user_object); + +int drm_fence_object_create(drm_device_t *dev, uint32_t type, + int emit, drm_fence_object_t **c_fence) +{ drm_fence_object_t *fence; + int ret; fence = kmem_cache_alloc(drm_cache.fence_object, GFP_KERNEL); if (!fence) @@ -434,23 +448,11 @@ static int drm_fence_object_create(drm_file_t * priv, uint32_t type, drm_fence_usage_deref_unlocked(dev, fence); return ret; } - - mutex_lock(&dev->struct_mutex); - ret = drm_add_user_object(priv, &fence->base, shareable); - mutex_unlock(&dev->struct_mutex); - if (ret) { - drm_fence_usage_deref_unlocked(dev, fence); - *c_fence = NULL; - *user_handle = 0; - return ret; - } - fence->base.type = drm_fence_type; - fence->base.remove = &drm_fence_object_destroy; - *user_handle = fence->base.hash.key; - *c_fence = fence; - + *c_fence = fence; return 0; } +EXPORT_SYMBOL(drm_fence_object_create); + void drm_fence_manager_init(drm_device_t * dev) { @@ -511,24 +513,29 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) DRM_COPY_FROM_USER_IOCTL(arg, (void __user *)data, sizeof(arg)); switch (arg.op) { - case drm_fence_create:{ - int emit = arg.flags & DRM_FENCE_FLAG_EMIT; - if (emit) - LOCK_TEST_WITH_RETURN(dev, filp); - ret = - drm_fence_object_create(priv, arg.type, - emit, - arg. - flags & - DRM_FENCE_FLAG_SHAREABLE, - &arg.handle, &fence); - if (ret) - return ret; - mutex_lock(&dev->struct_mutex); - atomic_inc(&fence->usage); - mutex_unlock(&dev->struct_mutex); - break; + case drm_fence_create: + if (arg.flags & DRM_FENCE_FLAG_EMIT) + LOCK_TEST_WITH_RETURN(dev, filp); + ret = drm_fence_object_create(dev, arg.type, + arg.flags & DRM_FENCE_FLAG_EMIT, + &fence); + if (ret) + return ret; + ret = drm_fence_add_user_object(priv, fence, + arg.flags & + DRM_FENCE_FLAG_SHAREABLE); + if (ret) { + drm_fence_usage_deref_unlocked(dev, fence); + return ret; } + + /* + * usage > 0. No need to lock dev->struct_mutex; + */ + + atomic_inc(&fence->usage); + arg.handle = fence->base.hash.key; + break; case drm_fence_destroy: mutex_lock(&dev->struct_mutex); uo = drm_lookup_user_object(priv, arg.handle); @@ -577,6 +584,23 @@ int drm_fence_ioctl(DRM_IOCTL_ARGS) return -EINVAL; ret = drm_fence_object_emit(dev, fence, arg.type); break; + case drm_fence_buffers: + if (!dev->bm.initialized) { + DRM_ERROR("Buffer object manager is not initialized\n"); + return -EINVAL; + } + LOCK_TEST_WITH_RETURN(dev, filp); + ret = drm_fence_buffer_objects(priv, NULL, NULL, &fence); + if (ret) + return ret; + ret = drm_fence_add_user_object(priv, fence, + arg.flags & + DRM_FENCE_FLAG_SHAREABLE); + if (ret) + return ret; + atomic_inc(&fence->usage); + arg.handle = fence->base.hash.key; + break; default: return -EINVAL; } diff --git a/shared-core/drm.h b/shared-core/drm.h index 1a43e0a..e39f888 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -659,7 +659,8 @@ typedef struct drm_fence_arg { drm_fence_signaled, drm_fence_flush, drm_fence_wait, - drm_fence_emit + drm_fence_emit, + drm_fence_buffers } op; } drm_fence_arg_t; -- 2.7.4