drm/syncobj: use newly allocated stub fences
Allocate a new private stub fence in drm_syncobj_assign_null_handle, instead of using a static stub fence. When userspace creates a fence with DRM_SYNCOBJ_CREATE_SIGNALED or when userspace signals a fence via DRM_IOCTL_SYNCOBJ_SIGNAL, the timestamp obtained when the fence is exported and queried with SYNC_IOC_FILE_INFO should match when the fence's status was changed from the perspective of userspace, which is during the respective ioctl. When a static stub fence started being used in by these ioctls, this behavior changed. Instead, the timestamp returned by SYNC_IOC_FILE_INFO became the first time anything used the static stub fence, which has no meaning to userspace. Signed-off-by: David Stevens <stevensd@chromium.org> Link: https://patchwork.freedesktop.org/patch/msgid/20210408095428.3983055-1-stevensd@google.com Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
parent
7513ce4902
commit
fd921693fe
|
@ -123,7 +123,9 @@ static const struct dma_fence_ops dma_fence_stub_ops = {
|
|||
/**
|
||||
* dma_fence_get_stub - return a signaled fence
|
||||
*
|
||||
* Return a stub fence which is already signaled.
|
||||
* Return a stub fence which is already signaled. The fence's
|
||||
* timestamp corresponds to the first time after boot this
|
||||
* function is called.
|
||||
*/
|
||||
struct dma_fence *dma_fence_get_stub(void)
|
||||
{
|
||||
|
@ -141,6 +143,29 @@ struct dma_fence *dma_fence_get_stub(void)
|
|||
}
|
||||
EXPORT_SYMBOL(dma_fence_get_stub);
|
||||
|
||||
/**
|
||||
* dma_fence_allocate_private_stub - return a private, signaled fence
|
||||
*
|
||||
* Return a newly allocated and signaled stub fence.
|
||||
*/
|
||||
struct dma_fence *dma_fence_allocate_private_stub(void)
|
||||
{
|
||||
struct dma_fence *fence;
|
||||
|
||||
fence = kzalloc(sizeof(*fence), GFP_KERNEL);
|
||||
if (fence == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dma_fence_init(fence,
|
||||
&dma_fence_stub_ops,
|
||||
&dma_fence_stub_lock,
|
||||
0, 0);
|
||||
dma_fence_signal(fence);
|
||||
|
||||
return fence;
|
||||
}
|
||||
EXPORT_SYMBOL(dma_fence_allocate_private_stub);
|
||||
|
||||
/**
|
||||
* dma_fence_context_alloc - allocate an array of fence contexts
|
||||
* @num: amount of contexts to allocate
|
||||
|
|
|
@ -350,12 +350,16 @@ EXPORT_SYMBOL(drm_syncobj_replace_fence);
|
|||
*
|
||||
* Assign a already signaled stub fence to the sync object.
|
||||
*/
|
||||
static void drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
|
||||
static int drm_syncobj_assign_null_handle(struct drm_syncobj *syncobj)
|
||||
{
|
||||
struct dma_fence *fence = dma_fence_get_stub();
|
||||
struct dma_fence *fence = dma_fence_allocate_private_stub();
|
||||
|
||||
if (IS_ERR(fence))
|
||||
return PTR_ERR(fence);
|
||||
|
||||
drm_syncobj_replace_fence(syncobj, fence);
|
||||
dma_fence_put(fence);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 5s default for wait submission */
|
||||
|
@ -478,6 +482,7 @@ EXPORT_SYMBOL(drm_syncobj_free);
|
|||
int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
|
||||
struct dma_fence *fence)
|
||||
{
|
||||
int ret;
|
||||
struct drm_syncobj *syncobj;
|
||||
|
||||
syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL);
|
||||
|
@ -488,8 +493,13 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags,
|
|||
INIT_LIST_HEAD(&syncobj->cb_list);
|
||||
spin_lock_init(&syncobj->lock);
|
||||
|
||||
if (flags & DRM_SYNCOBJ_CREATE_SIGNALED)
|
||||
drm_syncobj_assign_null_handle(syncobj);
|
||||
if (flags & DRM_SYNCOBJ_CREATE_SIGNALED) {
|
||||
ret = drm_syncobj_assign_null_handle(syncobj);
|
||||
if (ret < 0) {
|
||||
drm_syncobj_put(syncobj);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (fence)
|
||||
drm_syncobj_replace_fence(syncobj, fence);
|
||||
|
@ -1334,8 +1344,11 @@ drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < args->count_handles; i++)
|
||||
drm_syncobj_assign_null_handle(syncobjs[i]);
|
||||
for (i = 0; i < args->count_handles; i++) {
|
||||
ret = drm_syncobj_assign_null_handle(syncobjs[i]);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
drm_syncobj_array_free(syncobjs, args->count_handles);
|
||||
|
||||
|
|
|
@ -587,6 +587,7 @@ static inline signed long dma_fence_wait(struct dma_fence *fence, bool intr)
|
|||
}
|
||||
|
||||
struct dma_fence *dma_fence_get_stub(void);
|
||||
struct dma_fence *dma_fence_allocate_private_stub(void);
|
||||
u64 dma_fence_context_alloc(unsigned num);
|
||||
|
||||
#define DMA_FENCE_TRACE(f, fmt, args...) \
|
||||
|
|
Loading…
Reference in New Issue