[PATCH 5/5] amdgpu: use drm sync objects for shared semaphores (v4)

zhoucm1 david1.zhou at amd.com
Fri May 12 03:34:14 UTC 2017


1. generally, functions in amdgpu_cs.c should be with amdgpu_cs_ as prefix.
2. If I'm not wrong to your proposal, SYNCOBJ_IN is to semaphore wait 
while SYNCOBJ_OUT is to semaphore signal. SYNCOBJ_IN/OUT both are based 
on command submission ioctl, that means user space must generate CS when 
using semaphore? but with my understand, they should not be dependent 
with that, they can be used independently, right?

Anything I missed, if yes, pls correct me.

+		case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
+		case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:

Regards,
David Zhou
On 2017年05月12日 08:34, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This creates a new command submission chunk for amdgpu
> to add in and out sync objects around the submission.
>
> Sync objects are managed via the drm syncobj ioctls.
>
> The command submission interface is enhanced with two new
> chunks, one for syncobj pre submission dependencies,
> and one for post submission sync obj signalling,
> and just takes a list of handles for each.
>
> This is based on work originally done by David Zhou at AMD,
> with input from Christian Konig on what things should look like.
>
> In theory VkFences could be backed with sync objects and
> just get passed into the cs as syncobj handles as well.
>
> NOTE: this interface addition needs a version bump to expose
> it to userspace.
>
> v1.1: keep file reference on import.
> v2: move to using syncobjs
> v2.1: change some APIs to just use p pointer.
> v3: make more robust against CS failures, we now add the
> wait sems but only remove them once the CS job has been
> submitted.
> v4: rewrite names of API and base on new syncobj code.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  | 81 ++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 +-
>   include/uapi/drm/amdgpu_drm.h           |  6 +++
>   3 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index df25b32..e86c832 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -27,6 +27,7 @@
>   #include <linux/pagemap.h>
>   #include <drm/drmP.h>
>   #include <drm/amdgpu_drm.h>
> +#include <drm/drm_syncobj.h>
>   #include "amdgpu.h"
>   #include "amdgpu_trace.h"
>   
> @@ -217,6 +218,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
>   			break;
>   
>   		case AMDGPU_CHUNK_ID_DEPENDENCIES:
> +		case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
> +		case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
>   			break;
>   
>   		default:
> @@ -1008,6 +1011,40 @@ static int amdgpu_process_fence_dep(struct amdgpu_cs_parser *p,
>   	return 0;
>   }
>   
> +static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
> +						 uint32_t handle)
> +{
> +	int r;
> +	struct dma_fence *fence;
> +	r = drm_syncobj_fence_get(p->filp, handle, &fence);
> +	if (r)
> +		return r;
> +
> +	r = amdgpu_sync_fence(p->adev, &p->job->sync, fence);
> +	dma_fence_put(fence);
> +
> +	return r;
> +}
> +
> +static int amdgpu_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
> +					 struct amdgpu_cs_chunk *chunk)
> +{
> +	unsigned num_deps;
> +	int i, r;
> +	struct drm_amdgpu_cs_chunk_sem *deps;
> +
> +	deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
> +	num_deps = chunk->length_dw * 4 /
> +		sizeof(struct drm_amdgpu_cs_chunk_sem);
> +
> +	for (i = 0; i < num_deps; ++i) {
> +		r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle);
> +		if (r)
> +			return r;
> +	}
> +	return 0;
> +}
> +
>   static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
>   				  struct amdgpu_cs_parser *p)
>   {
> @@ -1022,12 +1059,54 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
>   			r = amdgpu_process_fence_dep(p, chunk);
>   			if (r)
>   				return r;
> +		} else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) {
> +			r = amdgpu_process_syncobj_in_dep(p, chunk);
> +			if (r)
> +				return r;
>   		}
>   	}
>   
>   	return 0;
>   }
>   
> +static int amdgpu_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
> +					  struct amdgpu_cs_chunk *chunk)
> +{
> +	unsigned num_deps;
> +	int i, r;
> +	struct drm_amdgpu_cs_chunk_sem *deps;
> +
> +	deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
> +	num_deps = chunk->length_dw * 4 /
> +		sizeof(struct drm_amdgpu_cs_chunk_sem);
> +
> +	for (i = 0; i < num_deps; ++i) {
> +		r = drm_syncobj_replace_fence(p->filp, deps[i].handle,
> +					      p->fence);
> +		if (r)
> +			return r;
> +	}
> +	return 0;
> +}
> +
> +static int amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
> +{
> +	int i, r;
> +
> +	for (i = 0; i < p->nchunks; ++i) {
> +		struct amdgpu_cs_chunk *chunk;
> +
> +		chunk = &p->chunks[i];
> +
> +		if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) {
> +			r = amdgpu_process_syncobj_out_dep(p, chunk);
> +			if (r)
> +				return r;
> +		}
> +	}
> +	return 0;
> +}
> +
>   static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
>   			    union drm_amdgpu_cs *cs)
>   {
> @@ -1055,7 +1134,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
>   	trace_amdgpu_cs_ioctl(job);
>   	amd_sched_entity_push_job(&job->base);
>   
> -	return 0;
> +	return amdgpu_cs_post_dependencies(p);
>   }
>   
>   int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index b76cd69..e95951e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -683,7 +683,7 @@ static struct drm_driver kms_driver = {
>   	.driver_features =
>   	    DRIVER_USE_AGP |
>   	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
> -	    DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
> +	    DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ,
>   	.load = amdgpu_driver_load_kms,
>   	.open = amdgpu_driver_open_kms,
>   	.preclose = amdgpu_driver_preclose_kms,
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 5797283..9881e27 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -390,6 +390,8 @@ struct drm_amdgpu_gem_va {
>   #define AMDGPU_CHUNK_ID_IB		0x01
>   #define AMDGPU_CHUNK_ID_FENCE		0x02
>   #define AMDGPU_CHUNK_ID_DEPENDENCIES	0x03
> +#define AMDGPU_CHUNK_ID_SYNCOBJ_IN      0x04
> +#define AMDGPU_CHUNK_ID_SYNCOBJ_OUT     0x05
>   
>   struct drm_amdgpu_cs_chunk {
>   	__u32		chunk_id;
> @@ -454,6 +456,10 @@ struct drm_amdgpu_cs_chunk_fence {
>   	__u32 offset;
>   };
>   
> +struct drm_amdgpu_cs_chunk_sem {
> +	__u32 handle;
> +};
> +
>   struct drm_amdgpu_cs_chunk_data {
>   	union {
>   		struct drm_amdgpu_cs_chunk_ib		ib_data;



More information about the amd-gfx mailing list