[Intel-gfx] [PATCH 51/55] drm/i915: Move the request/file and request/pid association to creation time

Tomas Elf tomas.elf at intel.com
Wed Jun 3 04:15:39 PDT 2015


On 29/05/2015 17:44, John.C.Harrison at Intel.com wrote:
> From: John Harrison <John.C.Harrison at Intel.com>
>
> In _i915_add_request(), the request is associated with a userland client.
> Specifically it is linked to the 'file' structure and the current user process
> is recorded. One problem here is that the current user process is not
> necessarily the same as when the request was submitted to the driver. This is
> especially true when the GPU scheduler arrives and decouples driver submission
> from hardware submission. Note also that it is only in the case where the add
> request comes from an execbuff call that there is a client to associate. Any
> other add request call is kernel only so does not need to do it.
>
> This patch moves the client association into a separate function. This is then
> called from the execbuffer code path itself at a sensible time. It also removes
> the now redundant 'file' pointer from the add request parameter list.
>
> An extra cleanup of the client association is also added to the request clean up
> code for the eventuality where the request is killed after association but
> before being submitted (e.g. due to out of memory error somewhere). Once the
> submission has happened, the request is on the request list and the regular
> request list removal will clear the association. Note that this still needs to
> happen at this point in time because the request might be kept floating around
> much longer (due to someone holding a reference count) and the client should not
> be worrying about this request after it has been retired.
>
> For: VIZ-5115
> Signed-off-by: John Harrison <John.C.Harrison at Intel.com>
> ---
>   drivers/gpu/drm/i915/i915_drv.h            |    7 ++--
>   drivers/gpu/drm/i915/i915_gem.c            |   56 ++++++++++++++++++++--------
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c |    6 ++-
>   3 files changed, 49 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index f9b6517..18bfc84 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2199,6 +2199,8 @@ int i915_gem_request_alloc(struct intel_engine_cs *ring,
>   			   struct drm_i915_gem_request **req_out);
>   void i915_gem_request_cancel(struct drm_i915_gem_request *req);
>   void i915_gem_request_free(struct kref *req_ref);
> +int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
> +				   struct drm_file *file);
>
>   static inline uint32_t
>   i915_gem_request_get_seqno(struct drm_i915_gem_request *req)
> @@ -2864,13 +2866,12 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
>   int __must_check i915_gpu_idle(struct drm_device *dev);
>   int __must_check i915_gem_suspend(struct drm_device *dev);
>   void __i915_add_request(struct drm_i915_gem_request *req,
> -			struct drm_file *file,
>   			struct drm_i915_gem_object *batch_obj,
>   			bool flush_caches);
>   #define i915_add_request(req) \
> -	__i915_add_request(req, NULL, NULL, true)
> +	__i915_add_request(req, NULL, true)
>   #define i915_add_request_no_flush(req) \
> -	__i915_add_request(req, NULL, NULL, false)
> +	__i915_add_request(req, NULL, false)
>   int __i915_wait_request(struct drm_i915_gem_request *req,
>   			unsigned reset_counter,
>   			bool interruptible,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 5aa0ad0..b8fe931 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -1331,6 +1331,33 @@ out:
>   	return ret;
>   }
>
> +int i915_gem_request_add_to_client(struct drm_i915_gem_request *req,
> +				   struct drm_file *file)
> +{
> +	struct drm_i915_private *dev_private;
> +	struct drm_i915_file_private *file_priv;
> +
> +	WARN_ON(!req || !file || req->file_priv);
> +
> +	if (!req || !file)
> +		return -EINVAL;
> +
> +	if (req->file_priv)
> +		return -EINVAL;
> +
> +	dev_private = req->ring->dev->dev_private;
> +	file_priv = file->driver_priv;
> +
> +	spin_lock(&file_priv->mm.lock);
> +	req->file_priv = file_priv;
> +	list_add_tail(&req->client_list, &file_priv->mm.request_list);
> +	spin_unlock(&file_priv->mm.lock);
> +
> +	req->pid = get_pid(task_pid(current));
> +
> +	return 0;
> +}
> +
>   static inline void
>   i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
>   {
> @@ -1343,6 +1370,9 @@ i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
>   	list_del(&request->client_list);
>   	request->file_priv = NULL;
>   	spin_unlock(&file_priv->mm.lock);
> +
> +	put_pid(request->pid);
> +	request->pid = NULL;
>   }
>
>   static void i915_gem_request_retire(struct drm_i915_gem_request *request)
> @@ -1362,8 +1392,6 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
>   	list_del_init(&request->list);
>   	i915_gem_request_remove_from_client(request);
>
> -	put_pid(request->pid);
> -
>   	i915_gem_request_unreference(request);
>   }
>
> @@ -2468,7 +2496,6 @@ i915_gem_get_seqno(struct drm_device *dev, u32 *seqno)
>    * going to happen on the hardware. This would be a Bad Thing(tm).
>    */
>   void __i915_add_request(struct drm_i915_gem_request *request,
> -			struct drm_file *file,
>   			struct drm_i915_gem_object *obj,
>   			bool flush_caches)
>   {
> @@ -2538,19 +2565,6 @@ void __i915_add_request(struct drm_i915_gem_request *request,
>
>   	request->emitted_jiffies = jiffies;
>   	list_add_tail(&request->list, &ring->request_list);
> -	request->file_priv = NULL;
> -
> -	if (file) {
> -		struct drm_i915_file_private *file_priv = file->driver_priv;
> -
> -		spin_lock(&file_priv->mm.lock);
> -		request->file_priv = file_priv;
> -		list_add_tail(&request->client_list,
> -			      &file_priv->mm.request_list);
> -		spin_unlock(&file_priv->mm.lock);
> -
> -		request->pid = get_pid(task_pid(current));
> -	}
>
>   	trace_i915_gem_request_add(request);
>
> @@ -2616,6 +2630,9 @@ void i915_gem_request_free(struct kref *req_ref)
>   						 typeof(*req), ref);
>   	struct intel_context *ctx = req->ctx;
>
> +	if (req->file_priv)
> +		i915_gem_request_remove_from_client(req);
> +
>   	if (ctx) {
>   		if (i915.enable_execlists) {
>   			struct intel_engine_cs *ring = req->ring;
> @@ -4320,6 +4337,13 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
>   		if (time_after_eq(request->emitted_jiffies, recent_enough))
>   			break;
>
> +		/*
> +		 * Note that the request might not have been submitted yet.
> +		 * In which case emitted_jiffies will be zero.
> +		 */
> +		if (!request->emitted_jiffies)
> +			continue;
> +
>   		target = request;
>   	}
>   	reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index e868ac1..52139c6 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1058,7 +1058,7 @@ i915_gem_execbuffer_retire_commands(struct i915_execbuffer_params *params)
>   	params->ring->gpu_caches_dirty = true;
>
>   	/* Add a breadcrumb for the completion of the batch buffer */
> -	__i915_add_request(params->request, params->file, params->batch_obj, true);
> +	__i915_add_request(params->request, params->batch_obj, true);
>   }
>
>   static int
> @@ -1612,6 +1612,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>   	if (ret)
>   		goto err_batch_unpin;
>
> +	ret = i915_gem_request_add_to_client(params->request, file);
> +	if (ret)
> +		goto err_batch_unpin;
> +
>   	/*
>   	 * Save assorted stuff away to pass through to *_submission().
>   	 * NB: This data should be 'persistent' and not local as it will
>


Reviewed-by: Tomas Elf <tomas.elf at intel.com>

Thanks,
Tomas



More information about the Intel-gfx mailing list