<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Tue, Jan 29, 2019, 3:01 AM Christian König <<a href="mailto:ckoenig.leichtzumerken@gmail.com">ckoenig.leichtzumerken@gmail.com</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Am 28.01.19 um 22:52 schrieb Marek Olšák:<br>
> From: Marek Olšák <<a href="mailto:marek.olsak@amd.com" target="_blank" rel="noreferrer">marek.olsak@amd.com</a>><br>
><br>
> Normal syncobjs signal when an IB finishes. Start syncobjs signal when<br>
> an IB starts.<br>
<br>
That approach has quite a number of problems (for example you can't <br>
allocate memory at this point).<br>
<br>
Better add a flag that we should only sync on scheduling for a <br>
dependency/syncobj instead.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I don't understand. Can you give me an example of the interface and how the implementation would look?</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto">Marek</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Christian.<br>
<br>
><br>
> Signed-off-by: Marek Olšák <<a href="mailto:marek.olsak@amd.com" target="_blank" rel="noreferrer">marek.olsak@amd.com</a>><br>
> ---<br>
>   drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +<br>
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 18 ++++++++++++++++++<br>
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  3 ++-<br>
>   include/uapi/drm/amdgpu_drm.h           | 13 ++++++++++++-<br>
>   4 files changed, 33 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> index d67f8b1dfe80..8e2f7e558bc9 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h<br>
> @@ -453,20 +453,21 @@ struct amdgpu_cs_parser {<br>
>       struct dma_fence                *fence;<br>
>       uint64_t                        bytes_moved_threshold;<br>
>       uint64_t                        bytes_moved_vis_threshold;<br>
>       uint64_t                        bytes_moved;<br>
>       uint64_t                        bytes_moved_vis;<br>
>       struct amdgpu_bo_list_entry     *evictable;<br>
>   <br>
>       /* user fence */<br>
>       struct amdgpu_bo_list_entry     uf_entry;<br>
>   <br>
> +     bool                            get_start_syncobj;<br>
>       unsigned num_post_dep_syncobjs;<br>
>       struct drm_syncobj **post_dep_syncobjs;<br>
>   };<br>
>   <br>
>   static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,<br>
>                                     uint32_t ib_idx, int idx)<br>
>   {<br>
>       return p->job->ibs[ib_idx].ptr[idx];<br>
>   }<br>
>   <br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c<br>
> index 1c49b8266d69..917f3818c61c 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c<br>
> @@ -1022,20 +1022,23 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,<br>
>               r = amdgpu_ctx_get_entity(parser->ctx, chunk_ib->ip_type,<br>
>                                         chunk_ib->ip_instance, chunk_ib->ring,<br>
>                                         &entity);<br>
>               if (r)<br>
>                       return r;<br>
>   <br>
>               if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)<br>
>                       parser->job->preamble_status |=<br>
>                               AMDGPU_PREAMBLE_IB_PRESENT;<br>
>   <br>
> +             if (chunk_ib->flags & AMDGPU_IB_FLAG_GET_START_SYNCOBJ)<br>
> +                     parser->get_start_syncobj = true;<br>
> +<br>
>               if (parser->entity && parser->entity != entity)<br>
>                       return -EINVAL;<br>
>   <br>
>               parser->entity = entity;<br>
>   <br>
>               ring = to_amdgpu_ring(entity->rq->sched);<br>
>               r =  amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ?<br>
>                                  chunk_ib->ib_bytes : 0, ib);<br>
>               if (r) {<br>
>                       DRM_ERROR("Failed to get ib !\n");<br>
> @@ -1227,20 +1230,35 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,<br>
>       amdgpu_mn_lock(p->mn);<br>
>       amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {<br>
>               struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e-><a href="http://tv.bo" rel="noreferrer noreferrer" target="_blank">tv.bo</a>);<br>
>   <br>
>               if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {<br>
>                       r = -ERESTARTSYS;<br>
>                       goto error_abort;<br>
>               }<br>
>       }<br>
>   <br>
> +     if (p->get_start_syncobj) {<br>
> +             struct drm_syncobj *syncobj;<br>
> +<br>
> +             r = drm_syncobj_create(&syncobj, 0,<br>
> +                                    &job->base.s_fence->scheduled);<br>
> +             if (r)<br>
> +                     goto error_abort;<br>
> +<br>
> +             r = drm_syncobj_get_handle(p->filp, syncobj,<br>
> +                                        &cs->out.start_syncobj);<br>
> +             if (r)<br>
> +                     goto error_abort;<br>
> +             drm_syncobj_put(syncobj);<br>
> +     }<br>
> +<br>
>       job->owner = p->filp;<br>
>       p->fence = dma_fence_get(&job->base.s_fence->finished);<br>
>   <br>
>       amdgpu_ctx_add_fence(p->ctx, entity, p->fence, &seq);<br>
>       amdgpu_cs_post_dependencies(p);<br>
>   <br>
>       if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) &&<br>
>           !p->ctx->preamble_presented) {<br>
>               job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;<br>
>               p->ctx->preamble_presented = true;<br>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
> index c806f984bcc5..a230a30722d4 100644<br>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c<br>
> @@ -64,23 +64,24 @@<br>
>    * - 3.18.0 - Export gpu always on cu bitmap<br>
>    * - 3.19.0 - Add support for UVD MJPEG decode<br>
>    * - 3.20.0 - Add support for local BOs<br>
>    * - 3.21.0 - Add DRM_AMDGPU_FENCE_TO_HANDLE ioctl<br>
>    * - 3.22.0 - Add DRM_AMDGPU_SCHED ioctl<br>
>    * - 3.23.0 - Add query for VRAM lost counter<br>
>    * - 3.24.0 - Add high priority compute support for gfx9<br>
>    * - 3.25.0 - Add support for sensor query info (stable pstate sclk/mclk).<br>
>    * - 3.26.0 - GFX9: Process AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE.<br>
>    * - 3.27.0 - Add new chunk to to AMDGPU_CS to enable BO_LIST creation.<br>
> + * - 3.28.0 - AMDGPU_IB_FLAG_GET_START_SYNCOBJ<br>
>    */<br>
>   #define KMS_DRIVER_MAJOR    3<br>
> -#define KMS_DRIVER_MINOR     27<br>
> +#define KMS_DRIVER_MINOR     28<br>
>   #define KMS_DRIVER_PATCHLEVEL       0<br>
>   <br>
>   int amdgpu_vram_limit = 0;<br>
>   int amdgpu_vis_vram_limit = 0;<br>
>   int amdgpu_gart_size = -1; /* auto */<br>
>   int amdgpu_gtt_size = -1; /* auto */<br>
>   int amdgpu_moverate = -1; /* auto */<br>
>   int amdgpu_benchmarking = 0;<br>
>   int amdgpu_testing = 0;<br>
>   int amdgpu_audio = -1;<br>
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h<br>
> index 662d379ea624..d0e0c99cea32 100644<br>
> --- a/include/uapi/drm/amdgpu_drm.h<br>
> +++ b/include/uapi/drm/amdgpu_drm.h<br>
> @@ -538,21 +538,23 @@ struct drm_amdgpu_cs_in {<br>
>       __u32           ctx_id;<br>
>       /**  Handle of resource list associated with CS */<br>
>       __u32           bo_list_handle;<br>
>       __u32           num_chunks;<br>
>       __u32           _pad;<br>
>       /** this points to __u64 * which point to cs chunks */<br>
>       __u64           chunks;<br>
>   };<br>
>   <br>
>   struct drm_amdgpu_cs_out {<br>
> -     __u64 handle;<br>
> +     __u64 handle; /* sequence number */<br>
> +     __u32 start_syncobj; /* signalled when IB execution begins */<br>
> +     __u32 _pad;<br>
>   };<br>
>   <br>
>   union drm_amdgpu_cs {<br>
>       struct drm_amdgpu_cs_in in;<br>
>       struct drm_amdgpu_cs_out out;<br>
>   };<br>
>   <br>
>   /* Specify flags to be used for IB */<br>
>   <br>
>   /* This IB should be submitted to CE */<br>
> @@ -566,20 +568,29 @@ union drm_amdgpu_cs {<br>
>   <br>
>   /* The IB fence should do the L2 writeback but not invalidate any shader<br>
>    * caches (L2/vL1/sL1/I$). */<br>
>   #define AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE (1 << 3)<br>
>   <br>
>   /* Set GDS_COMPUTE_MAX_WAVE_ID = DEFAULT before PACKET3_INDIRECT_BUFFER.<br>
>    * This will reset wave ID counters for the IB.<br>
>    */<br>
>   #define AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID (1 << 4)<br>
>   <br>
> +/* The CS ioctl will return a syncobj representing when all IBs begin<br>
> + * execution. If set, this applies to all IBs. The returned syncobj can be<br>
> + * used as an IB dependency for other IBs.<br>
> + *<br>
> + * This is used for GPU deadlock prevention when userspace uses mid-IB fences<br>
> + * to wait for mid-IB work on other rings.<br>
> + */<br>
> +#define AMDGPU_IB_FLAG_GET_START_SYNCOBJ (1 << 5)<br>
> +<br>
>   struct drm_amdgpu_cs_chunk_ib {<br>
>       __u32 _pad;<br>
>       /** AMDGPU_IB_FLAG_* */<br>
>       __u32 flags;<br>
>       /** Virtual address to begin IB execution */<br>
>       __u64 va_start;<br>
>       /** Size of submission */<br>
>       __u32 ib_bytes;<br>
>       /** HW IP to submit to */<br>
>       __u32 ip_type;<br>
<br>
</blockquote></div></div></div>