> -----Original Message----- > From: amd-gfx [mailto:[email protected]] On Behalf > Of Christian König > Sent: Monday, September 12, 2016 2:46 PM > To: Bas Nieuwenhuizen; Alex Deucher > Cc: Zhang, Jerry; [email protected] > Subject: Re: [PATCH] drm/amdgpu: add the interface of waiting multiple > fences (v3) > > Yeah, we added that later on. > > Looks like Alex (or somebody else) squashed the original and follow up > patch for libdrm together, but forgot to do so for the kernel side. > > Just wait a moment, if Alex can't find that of hand I'm going to take a > look through the branches tomorrow.
I found it. Looks like the commit message got messed up. I'll fix it up and send it out shortly. Alex > > Regards, > Christian. > > Am 12.09.2016 um 20:34 schrieb Bas Nieuwenhuizen: > > Seems like this is missing the update corresponding to libdrm patch > > "amdgpu: cs_wait_fences now can return the first signaled fence > > index". Is the kernel patch for that update also available or going > > to be sent to the list? > > > > Yours sincerely, > > Bas Nieuwenhuizen > > > > On Mon, Sep 12, 2016 at 6:40 PM, Alex Deucher <[email protected]> > wrote: > >> From: Junwei Zhang <[email protected]> > >> > >> v2: agd: rebase and squash in all the previous optimizations and > >> changes so everything compiles. > >> v3: squash in Slava's 32bit build fix > >> > >> Signed-off-by: Junwei Zhang <[email protected]> > >> Reviewed-by: Monk Liu <[email protected]> > >> Reviewed-by: Jammy Zhou <[email protected]> > >> --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 + > >> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 171 > ++++++++++++++++++++++++++++++++ > >> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 1 + > >> include/uapi/drm/amdgpu_drm.h | 27 +++++ > >> 4 files changed, 201 insertions(+) > >> > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> index 39baabe..4d6c42f 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h > >> @@ -1855,6 +1855,8 @@ int amdgpu_gem_op_ioctl(struct drm_device > *dev, void *data, > >> struct drm_file *filp); > >> int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file > *filp); > >> int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct > drm_file *filp); > >> +int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, > >> + struct drm_file *filp); > >> > >> int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, > >> struct drm_file *filp); > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > >> index e29e7b9..384856c 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c > >> @@ -1105,6 +1105,177 @@ int amdgpu_cs_wait_ioctl(struct drm_device > *dev, void *data, > >> } > >> > >> /** > >> + * amdgpu_cs_get_fence - helper to get fence from > drm_amdgpu_fence > >> + * > >> + * @adev: amdgpu device > >> + * @filp: file private > >> + * @user: drm_amdgpu_fence copied from user space > >> + */ > >> +static struct fence *amdgpu_cs_get_fence(struct amdgpu_device > *adev, > >> + struct drm_file *filp, > >> + struct drm_amdgpu_fence *user) > >> +{ > >> + struct amdgpu_ring *ring; > >> + struct amdgpu_ctx *ctx; > >> + struct fence *fence; > >> + int r; > >> + > >> + r = amdgpu_cs_get_ring(adev, user->ip_type, user->ip_instance, > >> + user->ring, &ring); > >> + if (r) > >> + return ERR_PTR(r); > >> + > >> + ctx = amdgpu_ctx_get(filp->driver_priv, user->ctx_id); > >> + if (ctx == NULL) > >> + return ERR_PTR(-EINVAL); > >> + > >> + fence = amdgpu_ctx_get_fence(ctx, ring, user->seq_no); > >> + amdgpu_ctx_put(ctx); > >> + > >> + return fence; > >> +} > >> + > >> +/** > >> + * amdgpu_cs_wait_all_fence - wait on all fences to signal > >> + * > >> + * @adev: amdgpu device > >> + * @filp: file private > >> + * @wait: wait parameters > >> + * @fences: array of drm_amdgpu_fence > >> + */ > >> +static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev, > >> + struct drm_file *filp, > >> + union drm_amdgpu_wait_fences *wait, > >> + struct drm_amdgpu_fence *fences) > >> +{ > >> + uint32_t fence_count = wait->in.fence_count; > >> + unsigned i; > >> + long r = 1; > >> + > >> + for (i = 0; i < fence_count; i++) { > >> + struct fence *fence; > >> + unsigned long timeout = amdgpu_gem_timeout(wait- > >in.timeout_ns); > >> + > >> + fence = amdgpu_cs_get_fence(adev, filp, &fences[i]); > >> + if (IS_ERR(fence)) > >> + return PTR_ERR(fence); > >> + else if (!fence) > >> + continue; > >> + > >> + r = fence_wait_timeout(fence, true, timeout); > >> + if (r < 0) > >> + return r; > >> + > >> + if (r == 0) > >> + break; > >> + } > >> + > >> + memset(wait, 0, sizeof(*wait)); > >> + wait->out.status = (r > 0); > >> + > >> + return 0; > >> +} > >> + > >> +/** > >> + * amdgpu_cs_wait_any_fence - wait on any fence to signal > >> + * > >> + * @adev: amdgpu device > >> + * @filp: file private > >> + * @wait: wait parameters > >> + * @fences: array of drm_amdgpu_fence > >> + */ > >> +static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev, > >> + struct drm_file *filp, > >> + union drm_amdgpu_wait_fences *wait, > >> + struct drm_amdgpu_fence *fences) > >> +{ > >> + unsigned long timeout = amdgpu_gem_timeout(wait- > >in.timeout_ns); > >> + uint32_t fence_count = wait->in.fence_count; > >> + struct fence **array; > >> + unsigned i; > >> + long r; > >> + > >> + /* Prepare the fence array */ > >> + array = (struct fence **)kcalloc(fence_count, sizeof(struct fence > >> *), > >> + GFP_KERNEL); > >> + if (array == NULL) > >> + return -ENOMEM; > >> + > >> + for (i = 0; i < fence_count; i++) { > >> + struct fence *fence; > >> + > >> + fence = amdgpu_cs_get_fence(adev, filp, &fences[i]); > >> + if (IS_ERR(fence)) { > >> + r = PTR_ERR(fence); > >> + goto err_free_fence_array; > >> + } else if (fence) { > >> + array[i] = fence; > >> + } else { /* NULL, the fence has been already signaled */ > >> + r = 1; > >> + goto out; > >> + } > >> + } > >> + > >> + r = fence_wait_any_timeout(array, fence_count, true, timeout); > >> + if (r < 0) > >> + goto err_free_fence_array; > >> + > >> +out: > >> + memset(wait, 0, sizeof(*wait)); > >> + wait->out.status = (r > 0); > >> + /* set return value 0 to indicate success */ > >> + r = 0; > >> + > >> +err_free_fence_array: > >> + for (i = 0; i < fence_count; i++) > >> + fence_put(array[i]); > >> + kfree(array); > >> + > >> + return r; > >> +} > >> + > >> +/** > >> + * amdgpu_cs_wait_fences_ioctl - wait for multiple command > submissions to finish > >> + * > >> + * @dev: drm device > >> + * @data: data from userspace > >> + * @filp: file private > >> + */ > >> +int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data, > >> + struct drm_file *filp) > >> +{ > >> + struct amdgpu_device *adev = dev->dev_private; > >> + union drm_amdgpu_wait_fences *wait = data; > >> + uint32_t fence_count = wait->in.fence_count; > >> + struct drm_amdgpu_fence *fences_user; > >> + struct drm_amdgpu_fence *fences; > >> + int r; > >> + > >> + /* Get the fences from userspace */ > >> + fences = kmalloc_array(fence_count, sizeof(struct > drm_amdgpu_fence), > >> + GFP_KERNEL); > >> + if (fences == NULL) > >> + return -ENOMEM; > >> + > >> + fences_user = (void __user *)(unsigned long)(wait->in.fences); > >> + if (copy_from_user(fences, fences_user, > >> + sizeof(struct drm_amdgpu_fence) * fence_count)) { > >> + r = -EFAULT; > >> + goto err_free_fences; > >> + } > >> + > >> + if (wait->in.wait_all) > >> + r = amdgpu_cs_wait_all_fences(adev, filp, wait, fences); > >> + else > >> + r = amdgpu_cs_wait_any_fence(adev, filp, wait, fences); > >> + > >> +err_free_fences: > >> + kfree(fences); > >> + > >> + return r; > >> +} > >> + > >> +/** > >> * amdgpu_cs_find_bo_va - find bo_va for VM address > >> * > >> * @parser: command submission parser context > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> index c2c7fb1..88ca1dc 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > >> @@ -775,6 +775,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] > = { > >> DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, > DRM_AUTH|DRM_RENDER_ALLOW), > >> DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, > DRM_AUTH|DRM_RENDER_ALLOW), > >> DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, > DRM_AUTH|DRM_RENDER_ALLOW), > >> + DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_FENCES, > amdgpu_cs_wait_fences_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), > >> DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, > amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), > >> DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, > DRM_AUTH|DRM_RENDER_ALLOW), > >> DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, > DRM_AUTH|DRM_RENDER_ALLOW), > >> diff --git a/include/uapi/drm/amdgpu_drm.h > b/include/uapi/drm/amdgpu_drm.h > >> index d6b5a21..dd9c99c 100644 > >> --- a/include/uapi/drm/amdgpu_drm.h > >> +++ b/include/uapi/drm/amdgpu_drm.h > >> @@ -50,6 +50,7 @@ extern "C" { > >> #define DRM_AMDGPU_WAIT_CS 0x09 > >> #define DRM_AMDGPU_GEM_OP 0x10 > >> #define DRM_AMDGPU_GEM_USERPTR 0x11 > >> +#define DRM_AMDGPU_WAIT_FENCES 0x12 > >> > >> #define DRM_IOCTL_AMDGPU_GEM_CREATE > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, > union drm_amdgpu_gem_create) > >> #define DRM_IOCTL_AMDGPU_GEM_MMAP > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union > drm_amdgpu_gem_mmap) > >> @@ -63,6 +64,7 @@ extern "C" { > >> #define DRM_IOCTL_AMDGPU_WAIT_CS > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union > drm_amdgpu_wait_cs) > >> #define DRM_IOCTL_AMDGPU_GEM_OP > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct > drm_amdgpu_gem_op) > >> #define DRM_IOCTL_AMDGPU_GEM_USERPTR > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, > struct drm_amdgpu_gem_userptr) > >> +#define DRM_IOCTL_AMDGPU_WAIT_FENCES > DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, > union drm_amdgpu_wait_fences) > >> > >> #define AMDGPU_GEM_DOMAIN_CPU 0x1 > >> #define AMDGPU_GEM_DOMAIN_GTT 0x2 > >> @@ -305,6 +307,31 @@ union drm_amdgpu_wait_cs { > >> struct drm_amdgpu_wait_cs_out out; > >> }; > >> > >> +struct drm_amdgpu_fence { > >> + __u32 ctx_id; > >> + __u32 ip_type; > >> + __u32 ip_instance; > >> + __u32 ring; > >> + __u64 seq_no; > >> +}; > >> + > >> +struct drm_amdgpu_wait_fences_in { > >> + /** This points to uint64_t * which points to fences */ > >> + __u64 fences; > >> + __u32 fence_count; > >> + __u32 wait_all; > >> + __u64 timeout_ns; > >> +}; > >> + > >> +struct drm_amdgpu_wait_fences_out { > >> + __u64 status; > >> +}; > >> + > >> +union drm_amdgpu_wait_fences { > >> + struct drm_amdgpu_wait_fences_in in; > >> + struct drm_amdgpu_wait_fences_out out; > >> +}; > >> + > >> #define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0 > >> #define AMDGPU_GEM_OP_SET_PLACEMENT 1 > >> > >> -- > >> 2.5.5 > >> > >> _______________________________________________ > >> amd-gfx mailing list > >> [email protected] > >> https://lists.freedesktop.org/mailman/listinfo/amd-gfx > > _______________________________________________ > > amd-gfx mailing list > > [email protected] > > https://lists.freedesktop.org/mailman/listinfo/amd-gfx > > > _______________________________________________ > amd-gfx mailing list > [email protected] > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/amd-gfx
