[PATCH 8/9] drm/syncobj: add timeline signal ioctl for syncobj v3

Lionel Landwerlin lionel.g.landwerlin at intel.com
Wed Mar 20 13:23:24 UTC 2019


On 20/03/2019 03:53, zhoucm1 wrote:
>
>
> On 2019年03月19日 19:54, Lionel Landwerlin wrote:
>> On 15/03/2019 12:09, Chunming Zhou wrote:
>>> v2: individually allocate chain array, since chain node is free 
>>> independently.
>>> v3: all existing points must be already signaled before cpu perform 
>>> signal operation,
>>>      so add check condition for that.
>>>
>>> Signed-off-by: Chunming Zhou <david1.zhou at amd.com>
>>> ---
>>>   drivers/gpu/drm/drm_internal.h |   2 +
>>>   drivers/gpu/drm/drm_ioctl.c    |   2 +
>>>   drivers/gpu/drm/drm_syncobj.c  | 103 
>>> +++++++++++++++++++++++++++++++++
>>>   include/uapi/drm/drm.h         |   1 +
>>>   4 files changed, 108 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/drm_internal.h 
>>> b/drivers/gpu/drm/drm_internal.h
>>> index dd11ae5f1eef..d9a483a5fce0 100644
>>> --- a/drivers/gpu/drm/drm_internal.h
>>> +++ b/drivers/gpu/drm/drm_internal.h
>>> @@ -190,6 +190,8 @@ int drm_syncobj_reset_ioctl(struct drm_device 
>>> *dev, void *data,
>>>                   struct drm_file *file_private);
>>>   int drm_syncobj_signal_ioctl(struct drm_device *dev, void *data,
>>>                    struct drm_file *file_private);
>>> +int drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void 
>>> *data,
>>> +                      struct drm_file *file_private);
>>>   int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>>>                   struct drm_file *file_private);
>>>   diff --git a/drivers/gpu/drm/drm_ioctl.c 
>>> b/drivers/gpu/drm/drm_ioctl.c
>>> index 92b3b7b2fd81..d337f161909c 100644
>>> --- a/drivers/gpu/drm/drm_ioctl.c
>>> +++ b/drivers/gpu/drm/drm_ioctl.c
>>> @@ -696,6 +696,8 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
>>>                 DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>>       DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_SIGNAL, drm_syncobj_signal_ioctl,
>>>                 DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>> +    DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL, 
>>> drm_syncobj_timeline_signal_ioctl,
>>> +              DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>>       DRM_IOCTL_DEF(DRM_IOCTL_SYNCOBJ_QUERY, drm_syncobj_query_ioctl,
>>>                 DRM_UNLOCKED|DRM_RENDER_ALLOW),
>>>       DRM_IOCTL_DEF(DRM_IOCTL_CRTC_GET_SEQUENCE, 
>>> drm_crtc_get_sequence_ioctl, DRM_UNLOCKED),
>>> diff --git a/drivers/gpu/drm/drm_syncobj.c 
>>> b/drivers/gpu/drm/drm_syncobj.c
>>> index 306c7b7e2770..eaeb038f97d7 100644
>>> --- a/drivers/gpu/drm/drm_syncobj.c
>>> +++ b/drivers/gpu/drm/drm_syncobj.c
>>> @@ -1183,6 +1183,109 @@ drm_syncobj_signal_ioctl(struct drm_device 
>>> *dev, void *data,
>>>       return ret;
>>>   }
>>>   +int
>>> +drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
>>> +                  struct drm_file *file_private)
>>> +{
>>> +    struct drm_syncobj_timeline_array *args = data;
>>> +    struct drm_syncobj **syncobjs;
>>> +    struct dma_fence_chain **chains;
>>> +    uint64_t *points;
>>> +    uint32_t i, j, timeline_count = 0;
>>> +    int ret;
>>> +
>>> +    if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ))
>>> +        return -EOPNOTSUPP;
>>> +
>>> +    if (args->pad != 0)
>>> +        return -EINVAL;
>>> +
>>> +    if (args->count_handles == 0)
>>> +        return -EINVAL;
>>> +
>>> +    ret = drm_syncobj_array_find(file_private,
>>> +                     u64_to_user_ptr(args->handles),
>>> +                     args->count_handles,
>>> +                     &syncobjs);
>>> +    if (ret < 0)
>>> +        return ret;
>>> +
>>> +    for (i = 0; i < args->count_handles; i++) {
>>> +        struct dma_fence_chain *chain;
>>> +                struct dma_fence *fence;
>>> +
>>> +                fence = drm_syncobj_fence_get(syncobjs[i]);
>>> +                chain = to_dma_fence_chain(fence);
>>> +                if (chain) {
>>> +                        struct dma_fence *iter;
>>> +
>>> +                        dma_fence_chain_for_each(iter, fence) {
>>> +                                if (!iter)
>>> +                                        break;
>>> +                if (!dma_fence_is_signaled(iter)) {
>>> +                    dma_fence_put(iter);
>>> +                    DRM_ERROR("Client must guarantee all existing 
>>> timeline points signaled before performing host signal operation!");
>>> +                    ret = -EPERM;
>>> +                    goto out;
>>
>>
>> Sorry if I'm failing to remember whether we discussed this before.
>>
>>
>> Signaling a point from the host should be fine even if the previous 
>> points in the timeline are not signaled.
> ok, will remove that checking.
>
>>
>> After all this can happen on the device side as well (out of order 
>> signaling).
>>
>>
>> I thought the thing we didn't want is out of order submission.
>>
>> Just checking the last chain node seqno against the host signal point 
>> should be enough.
>>
>>
>> What about simply returning -EPERM, we can warn the application from 
>> userspace?
> OK, will add that. 


Sorry for coming back to this again, but we probably ought to drop this 
check completely.

This is allowed on the device signaling side, so I'm not quite sure what 
that protects us from.


Also we do the check at this point in the signal_timeline_ioctl() 
function but there is nothing that says that when we later call the 
add_point() function this condition still holds.


-Lionel



More information about the dri-devel mailing list