diff mbox

[v3,1/3] drm/i915: simplify allocation of driver-internal requests

Message ID 1452162052-22573-2-git-send-email-david.s.gordon@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Gordon Jan. 7, 2016, 10:20 a.m. UTC
There are a number of places where the driver needs a request, but isn't
working on behalf of any specific user or in a specific context. At
present, we associate them with the per-engine default context. A future
patch will abolish those per-engine context pointers; but we can already
eliminate a lot of the references to them, just by making the allocator
allow NULL as a shorthand for "an appropriate context for this ring",
which will mean that the callers don't need to know anything about how
the "appropriate context" is found (e.g. per-ring vs per-device, etc).

So this patch renames the existing i915_gem_request_alloc(), and makes
it local (static inline), and replaces it with a wrapper that provides
a default if the context is NULL, and also has a nicer calling
convention (doesn't require a pointer to an output parameter). Then we
change all callers to use the new convention:
OLD:
	err = i915_gem_request_alloc(ring, user_ctx, &req);
	if (err) ...
NEW:
	req = i915_gem_request_alloc(ring, user_ctx);
	if (IS_ERR(req)) ...
OLD:
	err = i915_gem_request_alloc(ring, ring->default_context, &req);
	if (err) ...
NEW:
	req = i915_gem_request_alloc(ring, NULL);
	if (IS_ERR(req)) ...

Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h            |  6 ++--
 drivers/gpu/drm/i915/i915_gem.c            | 55 +++++++++++++++++++++++-------
 drivers/gpu/drm/i915/i915_gem_execbuffer.c | 14 +++++---
 drivers/gpu/drm/i915/intel_display.c       |  6 ++--
 drivers/gpu/drm/i915/intel_lrc.c           |  9 +++--
 drivers/gpu/drm/i915/intel_overlay.c       | 24 ++++++-------
 6 files changed, 74 insertions(+), 40 deletions(-)

Comments

Chris Wilson Jan. 7, 2016, 11:58 a.m. UTC | #1
On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
> There are a number of places where the driver needs a request, but isn't
> working on behalf of any specific user or in a specific context. At
> present, we associate them with the per-engine default context. A future
> patch will abolish those per-engine context pointers; but we can already
> eliminate a lot of the references to them, just by making the allocator
> allow NULL as a shorthand for "an appropriate context for this ring",
> which will mean that the callers don't need to know anything about how
> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
> 
> So this patch renames the existing i915_gem_request_alloc(), and makes
> it local (static inline), and replaces it with a wrapper that provides
> a default if the context is NULL, and also has a nicer calling
> convention (doesn't require a pointer to an output parameter). Then we
> change all callers to use the new convention:
> OLD:
> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, user_ctx);
> 	if (IS_ERR(req)) ...
> OLD:
> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, NULL);
> 	if (IS_ERR(req)) ...

Nak. You haven't fixed i915_gem_request_alloc() at all.

http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=breadcrumbs&id=82c72e1a2b4385f0ab07dccee45acef38303e96f
is the patch I have been carrying ever since.
-Chris
Jesse Barnes Jan. 7, 2016, 4:49 p.m. UTC | #2
On 01/07/2016 03:58 AM, Chris Wilson wrote:
> On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
>> There are a number of places where the driver needs a request, but isn't
>> working on behalf of any specific user or in a specific context. At
>> present, we associate them with the per-engine default context. A future
>> patch will abolish those per-engine context pointers; but we can already
>> eliminate a lot of the references to them, just by making the allocator
>> allow NULL as a shorthand for "an appropriate context for this ring",
>> which will mean that the callers don't need to know anything about how
>> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
>>
>> So this patch renames the existing i915_gem_request_alloc(), and makes
>> it local (static inline), and replaces it with a wrapper that provides
>> a default if the context is NULL, and also has a nicer calling
>> convention (doesn't require a pointer to an output parameter). Then we
>> change all callers to use the new convention:
>> OLD:
>> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
>> 	if (err) ...
>> NEW:
>> 	req = i915_gem_request_alloc(ring, user_ctx);
>> 	if (IS_ERR(req)) ...
>> OLD:
>> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
>> 	if (err) ...
>> NEW:
>> 	req = i915_gem_request_alloc(ring, NULL);
>> 	if (IS_ERR(req)) ...
> 
> Nak. You haven't fixed i915_gem_request_alloc() at all.
> 
> http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=breadcrumbs&id=82c72e1a2b4385f0ab07dccee45acef38303e96f
> is the patch I have been carrying ever since.

Can we stop with the "nak"?  This patch wraps the request alloc
differently than yours, but you haven't given details as to why you
think it's incorrect (see Dave's reply).

A patch review should contain one of the following:
  - Acknowledge and accept patch: provide Reviewed-by tag
  - Request for changes or fixes – clear list of actionable items to be
    addressed before Reviewed-by tag is given
  - Reject due to fundamental issue with approach or conflict with
    other work – clear reasons must be provided, in the case of
    conflict, JIRA or BZ of conflicting work should be provided for
    tracking and to ensure requirements are captured

If you really have a fundamental issue here (it doesn't sound like it)
you need to be clear about it.

Thanks,
Jesse
Chris Wilson Jan. 7, 2016, 4:53 p.m. UTC | #3
On Thu, Jan 07, 2016 at 08:49:38AM -0800, Jesse Barnes wrote:
> On 01/07/2016 03:58 AM, Chris Wilson wrote:
> > On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
> >> There are a number of places where the driver needs a request, but isn't
> >> working on behalf of any specific user or in a specific context. At
> >> present, we associate them with the per-engine default context. A future
> >> patch will abolish those per-engine context pointers; but we can already
> >> eliminate a lot of the references to them, just by making the allocator
> >> allow NULL as a shorthand for "an appropriate context for this ring",
> >> which will mean that the callers don't need to know anything about how
> >> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
> >>
> >> So this patch renames the existing i915_gem_request_alloc(), and makes
> >> it local (static inline), and replaces it with a wrapper that provides
> >> a default if the context is NULL, and also has a nicer calling
> >> convention (doesn't require a pointer to an output parameter). Then we
> >> change all callers to use the new convention:
> >> OLD:
> >> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
> >> 	if (err) ...
> >> NEW:
> >> 	req = i915_gem_request_alloc(ring, user_ctx);
> >> 	if (IS_ERR(req)) ...
> >> OLD:
> >> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
> >> 	if (err) ...
> >> NEW:
> >> 	req = i915_gem_request_alloc(ring, NULL);
> >> 	if (IS_ERR(req)) ...
> > 
> > Nak. You haven't fixed i915_gem_request_alloc() at all.
> > 
> > http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=breadcrumbs&id=82c72e1a2b4385f0ab07dccee45acef38303e96f
> > is the patch I have been carrying ever since.
> 
> Can we stop with the "nak"?  This patch wraps the request alloc
> differently than yours, but you haven't given details as to why you
> think it's incorrect (see Dave's reply).

I am annoyed that people do not review my patches and are duplicating
work I did last year and the year before, without attempting to fix
real bugs.
-Chris
Dave Gordon Jan. 12, 2016, 1:02 p.m. UTC | #4
On 07/01/16 16:53, Chris Wilson wrote:
> On Thu, Jan 07, 2016 at 08:49:38AM -0800, Jesse Barnes wrote:
>> On 01/07/2016 03:58 AM, Chris Wilson wrote:
>>> On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
>>>> There are a number of places where the driver needs a request, but isn't
>>>> working on behalf of any specific user or in a specific context. At
>>>> present, we associate them with the per-engine default context. A future
>>>> patch will abolish those per-engine context pointers; but we can already
>>>> eliminate a lot of the references to them, just by making the allocator
>>>> allow NULL as a shorthand for "an appropriate context for this ring",
>>>> which will mean that the callers don't need to know anything about how
>>>> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
>>>>
>>>> So this patch renames the existing i915_gem_request_alloc(), and makes
>>>> it local (static inline), and replaces it with a wrapper that provides
>>>> a default if the context is NULL, and also has a nicer calling
>>>> convention (doesn't require a pointer to an output parameter). Then we
>>>> change all callers to use the new convention:
>>>> OLD:
>>>> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
>>>> 	if (err) ...
>>>> NEW:
>>>> 	req = i915_gem_request_alloc(ring, user_ctx);
>>>> 	if (IS_ERR(req)) ...
>>>> OLD:
>>>> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
>>>> 	if (err) ...
>>>> NEW:
>>>> 	req = i915_gem_request_alloc(ring, NULL);
>>>> 	if (IS_ERR(req)) ...
>>>
>>> Nak. You haven't fixed i915_gem_request_alloc() at all.
>>>
>>> http://cgit.freedesktop.org/~ickle/linux-2.6/commit/?h=breadcrumbs&id=82c72e1a2b4385f0ab07dccee45acef38303e96f
>>> is the patch I have been carrying ever since.
>>
>> Can we stop with the "nak"?  This patch wraps the request alloc
>> differently than yours, but you haven't given details as to why you
>> think it's incorrect (see Dave's reply).
>
> I am annoyed that people do not review my patches and are duplicating
> work I did last year and the year before, without attempting to fix
> real bugs.
> -Chris

Chris, this patchset is totally directed towards fixing a specific bug, 
one which, moreover, arose a consequence of a patch YOU wrote:
b0366a5 drm/i915: intel_ring_initialized() must be simple and inline
(mea culpa too, obviously, since I was the one who rebased & pushed it).
Nick has a fix for the original bug, which involves reversing the 
teardown order, but can't now use it since b0366a5, so the bug remains. 
Nick's fix can be made to work if we replace the per-engine default 
contexts with the global one, which you've already agreed is a good idea 
(I think it was your idea in the first place!).

We can't take your patch because it doesn't apply to nightly. If you 
provide a standalone version that's not entangled with 100 other patches 
I'll happily review it. Or I might cherry-pick your existing one out of 
the 190-element patchset and try to rebase it onto nightly, which is how 
b0366a5 got in in the first place. I suspect it would look very much 
like mine then ...

Maybe we should just revert b0366a5 instead? Even though it was quite 
nice in itself ...

.Dave.
Daniel Vetter Jan. 12, 2016, 1:50 p.m. UTC | #5
On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
> There are a number of places where the driver needs a request, but isn't
> working on behalf of any specific user or in a specific context. At
> present, we associate them with the per-engine default context. A future
> patch will abolish those per-engine context pointers; but we can already
> eliminate a lot of the references to them, just by making the allocator
> allow NULL as a shorthand for "an appropriate context for this ring",
> which will mean that the callers don't need to know anything about how
> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
> 
> So this patch renames the existing i915_gem_request_alloc(), and makes
> it local (static inline), and replaces it with a wrapper that provides
> a default if the context is NULL, and also has a nicer calling
> convention (doesn't require a pointer to an output parameter). Then we
> change all callers to use the new convention:
> OLD:
> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, user_ctx);
> 	if (IS_ERR(req)) ...
> OLD:
> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, NULL);
> 	if (IS_ERR(req)) ...
> 
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h            |  6 ++--
>  drivers/gpu/drm/i915/i915_gem.c            | 55 +++++++++++++++++++++++-------
>  drivers/gpu/drm/i915/i915_gem_execbuffer.c | 14 +++++---
>  drivers/gpu/drm/i915/intel_display.c       |  6 ++--
>  drivers/gpu/drm/i915/intel_lrc.c           |  9 +++--
>  drivers/gpu/drm/i915/intel_overlay.c       | 24 ++++++-------
>  6 files changed, 74 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c6dd4db..c2b000a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2260,9 +2260,9 @@ struct drm_i915_gem_request {
>  
>  };
>  
> -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> -			   struct intel_context *ctx,
> -			   struct drm_i915_gem_request **req_out);
> +struct drm_i915_gem_request * __must_check
> +i915_gem_request_alloc(struct intel_engine_cs *engine,
> +		       struct intel_context *ctx);
>  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,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 6c60e04..c908ed1 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2688,9 +2688,10 @@ void i915_gem_request_free(struct kref *req_ref)
>  	kmem_cache_free(req->i915->requests, req);
>  }
>  
> -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> -			   struct intel_context *ctx,
> -			   struct drm_i915_gem_request **req_out)
> +static inline int
> +__i915_gem_request_alloc(struct intel_engine_cs *ring,
> +			 struct intel_context *ctx,
> +			 struct drm_i915_gem_request **req_out)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(ring->dev);
>  	struct drm_i915_gem_request *req;
> @@ -2753,6 +2754,31 @@ err:
>  	return ret;
>  }
>  
> +/**
> + * i915_gem_request_alloc - allocate a request structure
> + *
> + * @engine: engine that we wish to issue the request on.
> + * @ctx: context that the request will be associated with.
> + *       This can be NULL if the request is not directly related to
> + *       any specific user context, in which case this function will
> + *       choose an appropriate context to use.
> + *
> + * Returns a pointer to the allocated request if successful,
> + * or an error code if not.
> + */
> +struct drm_i915_gem_request *
> +i915_gem_request_alloc(struct intel_engine_cs *engine,
> +		       struct intel_context *ctx)
> +{
> +	struct drm_i915_gem_request *req;
> +	int err;
> +
> +	if (ctx == NULL)
> +		ctx = engine->default_context;

I think NULL vs. explicit dev_priv->kernel_context (or whatever it is) is
semantically equivalent enough that it doesn't matter. And we can easily
sed this (or an entire patch series for easy rebasing) if we change our
minds.

Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> +	err = __i915_gem_request_alloc(engine, ctx, &req);
> +	return err ? ERR_PTR(err) : req;
> +}
> +
>  void i915_gem_request_cancel(struct drm_i915_gem_request *req)
>  {
>  	intel_ring_reserved_space_cancel(req->ringbuf);
> @@ -3170,9 +3196,13 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
>  			return 0;
>  
>  		if (*to_req == NULL) {
> -			ret = i915_gem_request_alloc(to, to->default_context, to_req);
> -			if (ret)
> -				return ret;
> +			struct drm_i915_gem_request *req;
> +
> +			req = i915_gem_request_alloc(to, NULL);
> +			if (IS_ERR(req))
> +				return PTR_ERR(req);
> +
> +			*to_req = req;
>  		}
>  
>  		trace_i915_gem_ring_sync_to(*to_req, from, from_req);
> @@ -3372,9 +3402,9 @@ int i915_gpu_idle(struct drm_device *dev)
>  		if (!i915.enable_execlists) {
>  			struct drm_i915_gem_request *req;
>  
> -			ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -			if (ret)
> -				return ret;
> +			req = i915_gem_request_alloc(ring, NULL);
> +			if (IS_ERR(req))
> +				return PTR_ERR(req);
>  
>  			ret = i915_switch_context(req);
>  			if (ret) {
> @@ -4869,10 +4899,9 @@ i915_gem_init_hw(struct drm_device *dev)
>  	for_each_ring(ring, dev_priv, i) {
>  		struct drm_i915_gem_request *req;
>  
> -		WARN_ON(!ring->default_context);
> -
> -		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -		if (ret) {
> +		req = i915_gem_request_alloc(ring, NULL);
> +		if (IS_ERR(req)) {
> +			ret = PTR_ERR(req);
>  			i915_gem_cleanup_ringbuffer(dev);
>  			goto out;
>  		}
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index dccb517..dc6caeb 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1381,6 +1381,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>  		       struct drm_i915_gem_exec_object2 *exec)
>  {
>  	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_i915_gem_request *req = NULL;
>  	struct eb_vmas *eb;
>  	struct drm_i915_gem_object *batch_obj;
>  	struct drm_i915_gem_exec_object2 shadow_exec_entry;
> @@ -1602,11 +1603,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>  		params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
>  
>  	/* Allocate a request for this batch buffer nice and early. */
> -	ret = i915_gem_request_alloc(ring, ctx, &params->request);
> -	if (ret)
> +	req = i915_gem_request_alloc(ring, ctx);
> +	if (IS_ERR(req)) {
> +		ret = PTR_ERR(req);
>  		goto err_batch_unpin;
> +	}
>  
> -	ret = i915_gem_request_add_to_client(params->request, file);
> +	ret = i915_gem_request_add_to_client(req, file);
>  	if (ret)
>  		goto err_batch_unpin;
>  
> @@ -1622,6 +1625,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>  	params->dispatch_flags          = dispatch_flags;
>  	params->batch_obj               = batch_obj;
>  	params->ctx                     = ctx;
> +	params->request                 = req;
>  
>  	ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas);
>  
> @@ -1645,8 +1649,8 @@ err:
>  	 * must be freed again. If it was submitted then it is being tracked
>  	 * on the active request list and no clean up is required here.
>  	 */
> -	if (ret && params->request)
> -		i915_gem_request_cancel(params->request);
> +	if (ret && req)
> +		i915_gem_request_cancel(req);
>  
>  	mutex_unlock(&dev->struct_mutex);
>  
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ed9ab60..1f8f781 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11700,9 +11700,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>  					obj->last_write_req);
>  	} else {
>  		if (!request) {
> -			ret = i915_gem_request_alloc(ring, ring->default_context, &request);
> -			if (ret)
> +			request = i915_gem_request_alloc(ring, NULL);
> +			if (IS_ERR(request)) {
> +				ret = PTR_ERR(request);
>  				goto cleanup_unpin;
> +			}
>  		}
>  
>  		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 8096c6a..8b6542d 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -2510,11 +2510,10 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
>  	if (ctx != ring->default_context && ring->init_context) {
>  		struct drm_i915_gem_request *req;
>  
> -		ret = i915_gem_request_alloc(ring,
> -			ctx, &req);
> -		if (ret) {
> -			DRM_ERROR("ring create req: %d\n",
> -				ret);
> +		req = i915_gem_request_alloc(ring, ctx);
> +		if (IS_ERR(req)) {
> +			ret = PTR_ERR(req);
> +			DRM_ERROR("ring create req: %d\n", ret);
>  			goto error_ringbuf;
>  		}
>  
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 76f1980..9168413 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -240,9 +240,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
>  	WARN_ON(overlay->active);
>  	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
>  
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>  
>  	ret = intel_ring_begin(req, 4);
>  	if (ret) {
> @@ -283,9 +283,9 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
>  	if (tmp & (1 << 17))
>  		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
>  
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>  
>  	ret = intel_ring_begin(req, 2);
>  	if (ret) {
> @@ -349,9 +349,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
>  	 * of the hw. Do it in both cases */
>  	flip_addr |= OFC_UPDATE;
>  
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>  
>  	ret = intel_ring_begin(req, 6);
>  	if (ret) {
> @@ -423,9 +423,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
>  		/* synchronous slowpath */
>  		struct drm_i915_gem_request *req;
>  
> -		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -		if (ret)
> -			return ret;
> +		req = i915_gem_request_alloc(ring, NULL);
> +		if (IS_ERR(req))
> +			return PTR_ERR(req);
>  
>  		ret = intel_ring_begin(req, 2);
>  		if (ret) {
> -- 
> 1.9.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Chris Wilson Jan. 12, 2016, 1:56 p.m. UTC | #6
On Tue, Jan 12, 2016 at 02:50:28PM +0100, Daniel Vetter wrote:
> On Thu, Jan 07, 2016 at 10:20:50AM +0000, Dave Gordon wrote:
> > There are a number of places where the driver needs a request, but isn't
> > working on behalf of any specific user or in a specific context. At
> > present, we associate them with the per-engine default context. A future
> > patch will abolish those per-engine context pointers; but we can already
> > eliminate a lot of the references to them, just by making the allocator
> > allow NULL as a shorthand for "an appropriate context for this ring",
> > which will mean that the callers don't need to know anything about how
> > the "appropriate context" is found (e.g. per-ring vs per-device, etc).
> > 
> > So this patch renames the existing i915_gem_request_alloc(), and makes
> > it local (static inline), and replaces it with a wrapper that provides
> > a default if the context is NULL, and also has a nicer calling
> > convention (doesn't require a pointer to an output parameter). Then we
> > change all callers to use the new convention:
> > OLD:
> > 	err = i915_gem_request_alloc(ring, user_ctx, &req);
> > 	if (err) ...
> > NEW:
> > 	req = i915_gem_request_alloc(ring, user_ctx);
> > 	if (IS_ERR(req)) ...
> > OLD:
> > 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
> > 	if (err) ...
> > NEW:
> > 	req = i915_gem_request_alloc(ring, NULL);
> > 	if (IS_ERR(req)) ...
> > 
> > Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
> > ---
> >  drivers/gpu/drm/i915/i915_drv.h            |  6 ++--
> >  drivers/gpu/drm/i915/i915_gem.c            | 55 +++++++++++++++++++++++-------
> >  drivers/gpu/drm/i915/i915_gem_execbuffer.c | 14 +++++---
> >  drivers/gpu/drm/i915/intel_display.c       |  6 ++--
> >  drivers/gpu/drm/i915/intel_lrc.c           |  9 +++--
> >  drivers/gpu/drm/i915/intel_overlay.c       | 24 ++++++-------
> >  6 files changed, 74 insertions(+), 40 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> > index c6dd4db..c2b000a 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -2260,9 +2260,9 @@ struct drm_i915_gem_request {
> >  
> >  };
> >  
> > -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> > -			   struct intel_context *ctx,
> > -			   struct drm_i915_gem_request **req_out);
> > +struct drm_i915_gem_request * __must_check
> > +i915_gem_request_alloc(struct intel_engine_cs *engine,
> > +		       struct intel_context *ctx);
> >  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,
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index 6c60e04..c908ed1 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -2688,9 +2688,10 @@ void i915_gem_request_free(struct kref *req_ref)
> >  	kmem_cache_free(req->i915->requests, req);
> >  }
> >  
> > -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> > -			   struct intel_context *ctx,
> > -			   struct drm_i915_gem_request **req_out)
> > +static inline int
> > +__i915_gem_request_alloc(struct intel_engine_cs *ring,
> > +			 struct intel_context *ctx,
> > +			 struct drm_i915_gem_request **req_out)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(ring->dev);
> >  	struct drm_i915_gem_request *req;
> > @@ -2753,6 +2754,31 @@ err:
> >  	return ret;
> >  }
> >  
> > +/**
> > + * i915_gem_request_alloc - allocate a request structure
> > + *
> > + * @engine: engine that we wish to issue the request on.
> > + * @ctx: context that the request will be associated with.
> > + *       This can be NULL if the request is not directly related to
> > + *       any specific user context, in which case this function will
> > + *       choose an appropriate context to use.
> > + *
> > + * Returns a pointer to the allocated request if successful,
> > + * or an error code if not.
> > + */
> > +struct drm_i915_gem_request *
> > +i915_gem_request_alloc(struct intel_engine_cs *engine,
> > +		       struct intel_context *ctx)
> > +{
> > +	struct drm_i915_gem_request *req;
> > +	int err;
> > +
> > +	if (ctx == NULL)
> > +		ctx = engine->default_context;
> 
> I think NULL vs. explicit dev_priv->kernel_context (or whatever it is) is
> semantically equivalent enough that it doesn't matter. And we can easily
> sed this (or an entire patch series for easy rebasing) if we change our
> minds.

But we were removing the engine->default_context as it complicated the
rest of the code. I strongly prefer keeping the contexts explicit as
context separation should be first and foremost in the driver.
-Chris
Chris Wilson Jan. 12, 2016, 2:27 p.m. UTC | #7
On Tue, Jan 12, 2016 at 01:56:48PM +0000, Chris Wilson wrote:
> But we were removing the engine->default_context as it complicated the
> rest of the code. I strongly prefer keeping the contexts explicit as
> context separation should be first and foremost in the driver.

$ git grep kernel_context -- drivers/gpu/drm/i915/ | grep request_alloc
drivers/gpu/drm/i915/i915_gem_evict.c:		req = i915_gem_request_alloc(ring, dev_priv->kernel_context);
drivers/gpu/drm/i915/intel_overlay.c:	return i915_gem_request_alloc(ring, dev_priv->kernel_context);

Changing those *two* callsites to pass NULL seems on the odd side, and
at least for the eviction case discards important information.
-Chris
Dave Gordon Jan. 13, 2016, 1:27 p.m. UTC | #8
On 12/01/16 14:27, Chris Wilson wrote:
> On Tue, Jan 12, 2016 at 01:56:48PM +0000, Chris Wilson wrote:
>> But we were removing the engine->default_context as it complicated the
>> rest of the code. I strongly prefer keeping the contexts explicit as
>> context separation should be first and foremost in the driver.
>
> $ git grep kernel_context -- drivers/gpu/drm/i915/ | grep request_alloc
> drivers/gpu/drm/i915/i915_gem_evict.c:		req = i915_gem_request_alloc(ring, dev_priv->kernel_context);
> drivers/gpu/drm/i915/intel_overlay.c:	return i915_gem_request_alloc(ring, dev_priv->kernel_context);
>
> Changing those *two* callsites to pass NULL seems on the odd side, and
> at least for the eviction case discards important information.
> -Chris

Those specific lines won't be touched by my patch, as *they don't 
actually exist in today's drm-intel-nightly* branch. If you want to add 
*new* calls to i915_gem_request_alloc() such as the above then you're 
quite free to pass any context you want, whether it's a real user 
context, the default kernel context explicitly, if you think it's 
important that the reader know that that specific context will be used; 
or NULL if you don't care what context is used.

dev_priv->kernel_context carries exactly the same amount of information 
as NULL; they both mean "I don't have a specific context to use here, so 
(I'm going to) use the one the driver provides for such activities". 
Having the option of using NULL rather than"dev_priv->kernel_context" 
explicitly doesn't prevent you from doing so where the caller cares. But 
I think most callers *don't* care.

.Dave.
Chris Wilson Jan. 13, 2016, 1:41 p.m. UTC | #9
On Wed, Jan 13, 2016 at 01:27:51PM +0000, Dave Gordon wrote:
> On 12/01/16 14:27, Chris Wilson wrote:
> >On Tue, Jan 12, 2016 at 01:56:48PM +0000, Chris Wilson wrote:
> >>But we were removing the engine->default_context as it complicated the
> >>rest of the code. I strongly prefer keeping the contexts explicit as
> >>context separation should be first and foremost in the driver.
> >
> >$ git grep kernel_context -- drivers/gpu/drm/i915/ | grep request_alloc
> >drivers/gpu/drm/i915/i915_gem_evict.c:		req = i915_gem_request_alloc(ring, dev_priv->kernel_context);
> >drivers/gpu/drm/i915/intel_overlay.c:	return i915_gem_request_alloc(ring, dev_priv->kernel_context);
> >
> >Changing those *two* callsites to pass NULL seems on the odd side, and
> >at least for the eviction case discards important information.
> >-Chris
> 
> Those specific lines won't be touched by my patch, as *they don't
> actually exist in today's drm-intel-nightly* branch. If you want to
> add *new* calls to i915_gem_request_alloc() such as the above then
> you're quite free to pass any context you want, whether it's a real
> user context, the default kernel context explicitly, if you think
> it's important that the reader know that that specific context will
> be used; or NULL if you don't care what context is used.

They are the same calls as the ones you are patching. They are not new
calls, they are the only users of the kernel_context for emission. Which
is why I am suggesting a different series of steps to take in tidying
this up.
-Chris
Dave Gordon Jan. 13, 2016, 6:46 p.m. UTC | #10
On 13/01/16 13:41, Chris Wilson wrote:
> On Wed, Jan 13, 2016 at 01:27:51PM +0000, Dave Gordon wrote:
>> On 12/01/16 14:27, Chris Wilson wrote:
>>> On Tue, Jan 12, 2016 at 01:56:48PM +0000, Chris Wilson wrote:
>>>> But we were removing the engine->default_context as it complicated the
>>>> rest of the code. I strongly prefer keeping the contexts explicit as
>>>> context separation should be first and foremost in the driver.
>>>
>>> $ git grep kernel_context -- drivers/gpu/drm/i915/ | grep request_alloc
>>> drivers/gpu/drm/i915/i915_gem_evict.c:		req = i915_gem_request_alloc(ring, dev_priv->kernel_context);
>>> drivers/gpu/drm/i915/intel_overlay.c:	return i915_gem_request_alloc(ring, dev_priv->kernel_context);
>>>
>>> Changing those *two* callsites to pass NULL seems on the odd side, and
>>> at least for the eviction case discards important information.
>>> -Chris
>>
>> Those specific lines won't be touched by my patch, as *they don't
>> actually exist in today's drm-intel-nightly* branch. If you want to
>> add *new* calls to i915_gem_request_alloc() such as the above then
>> you're quite free to pass any context you want, whether it's a real
>> user context, the default kernel context explicitly, if you think
>> it's important that the reader know that that specific context will
>> be used; or NULL if you don't care what context is used.
>
> They are the same calls as the ones you are patching. They are not new
> calls, they are the only users of the kernel_context for emission. Which
> is why I am suggesting a different series of steps to take in tidying
> this up.
> -Chris

As of now (i.e. pre-conversion of the default_context pointer), there 
are *eight* calls to i915_gem_request_alloc(), but NONE in i915_gem_evict.c:

drm-intel-nightly$ git grep -c 
'i915_gem_request_alloc(.*default_context' -- drivers/gpu/drm/i915/
drivers/gpu/drm/i915/i915_gem.c:3
drivers/gpu/drm/i915/intel_display.c:1
drivers/gpu/drm/i915/intel_overlay.c:4

So you must be looking in a different tree, presumably one where you've 
already done some other bunch of cleanups in a different order.

.Dave.
Chris Wilson Jan. 13, 2016, 8:23 p.m. UTC | #11
On Wed, Jan 13, 2016 at 06:46:08PM +0000, Dave Gordon wrote:
> On 13/01/16 13:41, Chris Wilson wrote:
> >On Wed, Jan 13, 2016 at 01:27:51PM +0000, Dave Gordon wrote:
> >>On 12/01/16 14:27, Chris Wilson wrote:
> >>>On Tue, Jan 12, 2016 at 01:56:48PM +0000, Chris Wilson wrote:
> >>>>But we were removing the engine->default_context as it complicated the
> >>>>rest of the code. I strongly prefer keeping the contexts explicit as
> >>>>context separation should be first and foremost in the driver.
> >>>
> >>>$ git grep kernel_context -- drivers/gpu/drm/i915/ | grep request_alloc
> >>>drivers/gpu/drm/i915/i915_gem_evict.c:		req = i915_gem_request_alloc(ring, dev_priv->kernel_context);
> >>>drivers/gpu/drm/i915/intel_overlay.c:	return i915_gem_request_alloc(ring, dev_priv->kernel_context);
> >>>
> >>>Changing those *two* callsites to pass NULL seems on the odd side, and
> >>>at least for the eviction case discards important information.
> >>>-Chris
> >>
> >>Those specific lines won't be touched by my patch, as *they don't
> >>actually exist in today's drm-intel-nightly* branch. If you want to
> >>add *new* calls to i915_gem_request_alloc() such as the above then
> >>you're quite free to pass any context you want, whether it's a real
> >>user context, the default kernel context explicitly, if you think
> >>it's important that the reader know that that specific context will
> >>be used; or NULL if you don't care what context is used.
> >
> >They are the same calls as the ones you are patching. They are not new
> >calls, they are the only users of the kernel_context for emission. Which
> >is why I am suggesting a different series of steps to take in tidying
> >this up.
> >-Chris
> 
> As of now (i.e. pre-conversion of the default_context pointer),
> there are *eight* calls to i915_gem_request_alloc(), but NONE in
> i915_gem_evict.c:
> 
> drm-intel-nightly$ git grep -c
> 'i915_gem_request_alloc(.*default_context' -- drivers/gpu/drm/i915/
> drivers/gpu/drm/i915/i915_gem.c:3
> drivers/gpu/drm/i915/intel_display.c:1
> drivers/gpu/drm/i915/intel_overlay.c:4
> 
> So you must be looking in a different tree, presumably one where
> you've already done some other bunch of cleanups in a different
> order.

Exactly. I disagree with the notion of an implicit context, and have
outlined a course of action where there is only a single active user of
the kernel context (overlay). And if we talk nicely to Ville we could
eliminate the overlay as well. The other use of that kernel context for
request construction is then to provide a means to flush other contexts
from the GPU - we don't use it for anything other than pinned storage.

For execlists we can do away with the kernel context entirely, we don't
even need it for the HWS if we just switch to per-context seqno. (It is
not required for flushing the last context.) I have no idea what the guc
is doing with it though, or whether it is being set up in hardware just
because it is there (even though we never use it).
-Chris
Nick Hoath Jan. 18, 2016, 4:16 p.m. UTC | #12
On 07/01/2016 10:20, Dave Gordon wrote:
> There are a number of places where the driver needs a request, but isn't
> working on behalf of any specific user or in a specific context. At
> present, we associate them with the per-engine default context. A future
> patch will abolish those per-engine context pointers; but we can already
> eliminate a lot of the references to them, just by making the allocator
> allow NULL as a shorthand for "an appropriate context for this ring",
> which will mean that the callers don't need to know anything about how
> the "appropriate context" is found (e.g. per-ring vs per-device, etc).
>
> So this patch renames the existing i915_gem_request_alloc(), and makes
> it local (static inline), and replaces it with a wrapper that provides
> a default if the context is NULL, and also has a nicer calling
> convention (doesn't require a pointer to an output parameter). Then we
> change all callers to use the new convention:
> OLD:
> 	err = i915_gem_request_alloc(ring, user_ctx, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, user_ctx);
> 	if (IS_ERR(req)) ...
> OLD:
> 	err = i915_gem_request_alloc(ring, ring->default_context, &req);
> 	if (err) ...
> NEW:
> 	req = i915_gem_request_alloc(ring, NULL);
> 	if (IS_ERR(req)) ...
>
> Signed-off-by: Dave Gordon <david.s.gordon@intel.com>

Reviewed-by: Nick Hoath <nicholas.hoath@intel.com>

> ---
>   drivers/gpu/drm/i915/i915_drv.h            |  6 ++--
>   drivers/gpu/drm/i915/i915_gem.c            | 55 +++++++++++++++++++++++-------
>   drivers/gpu/drm/i915/i915_gem_execbuffer.c | 14 +++++---
>   drivers/gpu/drm/i915/intel_display.c       |  6 ++--
>   drivers/gpu/drm/i915/intel_lrc.c           |  9 +++--
>   drivers/gpu/drm/i915/intel_overlay.c       | 24 ++++++-------
>   6 files changed, 74 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c6dd4db..c2b000a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2260,9 +2260,9 @@ struct drm_i915_gem_request {
>
>   };
>
> -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> -			   struct intel_context *ctx,
> -			   struct drm_i915_gem_request **req_out);
> +struct drm_i915_gem_request * __must_check
> +i915_gem_request_alloc(struct intel_engine_cs *engine,
> +		       struct intel_context *ctx);
>   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,
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index 6c60e04..c908ed1 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -2688,9 +2688,10 @@ void i915_gem_request_free(struct kref *req_ref)
>   	kmem_cache_free(req->i915->requests, req);
>   }
>
> -int i915_gem_request_alloc(struct intel_engine_cs *ring,
> -			   struct intel_context *ctx,
> -			   struct drm_i915_gem_request **req_out)
> +static inline int
> +__i915_gem_request_alloc(struct intel_engine_cs *ring,
> +			 struct intel_context *ctx,
> +			 struct drm_i915_gem_request **req_out)
>   {
>   	struct drm_i915_private *dev_priv = to_i915(ring->dev);
>   	struct drm_i915_gem_request *req;
> @@ -2753,6 +2754,31 @@ err:
>   	return ret;
>   }
>
> +/**
> + * i915_gem_request_alloc - allocate a request structure
> + *
> + * @engine: engine that we wish to issue the request on.
> + * @ctx: context that the request will be associated with.
> + *       This can be NULL if the request is not directly related to
> + *       any specific user context, in which case this function will
> + *       choose an appropriate context to use.
> + *
> + * Returns a pointer to the allocated request if successful,
> + * or an error code if not.
> + */
> +struct drm_i915_gem_request *
> +i915_gem_request_alloc(struct intel_engine_cs *engine,
> +		       struct intel_context *ctx)
> +{
> +	struct drm_i915_gem_request *req;
> +	int err;
> +
> +	if (ctx == NULL)
> +		ctx = engine->default_context;
> +	err = __i915_gem_request_alloc(engine, ctx, &req);
> +	return err ? ERR_PTR(err) : req;
> +}
> +
>   void i915_gem_request_cancel(struct drm_i915_gem_request *req)
>   {
>   	intel_ring_reserved_space_cancel(req->ringbuf);
> @@ -3170,9 +3196,13 @@ __i915_gem_object_sync(struct drm_i915_gem_object *obj,
>   			return 0;
>
>   		if (*to_req == NULL) {
> -			ret = i915_gem_request_alloc(to, to->default_context, to_req);
> -			if (ret)
> -				return ret;
> +			struct drm_i915_gem_request *req;
> +
> +			req = i915_gem_request_alloc(to, NULL);
> +			if (IS_ERR(req))
> +				return PTR_ERR(req);
> +
> +			*to_req = req;
>   		}
>
>   		trace_i915_gem_ring_sync_to(*to_req, from, from_req);
> @@ -3372,9 +3402,9 @@ int i915_gpu_idle(struct drm_device *dev)
>   		if (!i915.enable_execlists) {
>   			struct drm_i915_gem_request *req;
>
> -			ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -			if (ret)
> -				return ret;
> +			req = i915_gem_request_alloc(ring, NULL);
> +			if (IS_ERR(req))
> +				return PTR_ERR(req);
>
>   			ret = i915_switch_context(req);
>   			if (ret) {
> @@ -4869,10 +4899,9 @@ i915_gem_init_hw(struct drm_device *dev)
>   	for_each_ring(ring, dev_priv, i) {
>   		struct drm_i915_gem_request *req;
>
> -		WARN_ON(!ring->default_context);
> -
> -		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -		if (ret) {
> +		req = i915_gem_request_alloc(ring, NULL);
> +		if (IS_ERR(req)) {
> +			ret = PTR_ERR(req);
>   			i915_gem_cleanup_ringbuffer(dev);
>   			goto out;
>   		}
> diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> index dccb517..dc6caeb 100644
> --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
> @@ -1381,6 +1381,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>   		       struct drm_i915_gem_exec_object2 *exec)
>   {
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_i915_gem_request *req = NULL;
>   	struct eb_vmas *eb;
>   	struct drm_i915_gem_object *batch_obj;
>   	struct drm_i915_gem_exec_object2 shadow_exec_entry;
> @@ -1602,11 +1603,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>   		params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
>
>   	/* Allocate a request for this batch buffer nice and early. */
> -	ret = i915_gem_request_alloc(ring, ctx, &params->request);
> -	if (ret)
> +	req = i915_gem_request_alloc(ring, ctx);
> +	if (IS_ERR(req)) {
> +		ret = PTR_ERR(req);
>   		goto err_batch_unpin;
> +	}
>
> -	ret = i915_gem_request_add_to_client(params->request, file);
> +	ret = i915_gem_request_add_to_client(req, file);
>   	if (ret)
>   		goto err_batch_unpin;
>
> @@ -1622,6 +1625,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
>   	params->dispatch_flags          = dispatch_flags;
>   	params->batch_obj               = batch_obj;
>   	params->ctx                     = ctx;
> +	params->request                 = req;
>
>   	ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas);
>
> @@ -1645,8 +1649,8 @@ err:
>   	 * must be freed again. If it was submitted then it is being tracked
>   	 * on the active request list and no clean up is required here.
>   	 */
> -	if (ret && params->request)
> -		i915_gem_request_cancel(params->request);
> +	if (ret && req)
> +		i915_gem_request_cancel(req);
>
>   	mutex_unlock(&dev->struct_mutex);
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index ed9ab60..1f8f781 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11700,9 +11700,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>   					obj->last_write_req);
>   	} else {
>   		if (!request) {
> -			ret = i915_gem_request_alloc(ring, ring->default_context, &request);
> -			if (ret)
> +			request = i915_gem_request_alloc(ring, NULL);
> +			if (IS_ERR(request)) {
> +				ret = PTR_ERR(request);
>   				goto cleanup_unpin;
> +			}
>   		}
>
>   		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 8096c6a..8b6542d 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -2510,11 +2510,10 @@ int intel_lr_context_deferred_alloc(struct intel_context *ctx,
>   	if (ctx != ring->default_context && ring->init_context) {
>   		struct drm_i915_gem_request *req;
>
> -		ret = i915_gem_request_alloc(ring,
> -			ctx, &req);
> -		if (ret) {
> -			DRM_ERROR("ring create req: %d\n",
> -				ret);
> +		req = i915_gem_request_alloc(ring, ctx);
> +		if (IS_ERR(req)) {
> +			ret = PTR_ERR(req);
> +			DRM_ERROR("ring create req: %d\n", ret);
>   			goto error_ringbuf;
>   		}
>
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index 76f1980..9168413 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -240,9 +240,9 @@ static int intel_overlay_on(struct intel_overlay *overlay)
>   	WARN_ON(overlay->active);
>   	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
>
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>
>   	ret = intel_ring_begin(req, 4);
>   	if (ret) {
> @@ -283,9 +283,9 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
>   	if (tmp & (1 << 17))
>   		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
>
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>
>   	ret = intel_ring_begin(req, 2);
>   	if (ret) {
> @@ -349,9 +349,9 @@ static int intel_overlay_off(struct intel_overlay *overlay)
>   	 * of the hw. Do it in both cases */
>   	flip_addr |= OFC_UPDATE;
>
> -	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -	if (ret)
> -		return ret;
> +	req = i915_gem_request_alloc(ring, NULL);
> +	if (IS_ERR(req))
> +		return PTR_ERR(req);
>
>   	ret = intel_ring_begin(req, 6);
>   	if (ret) {
> @@ -423,9 +423,9 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
>   		/* synchronous slowpath */
>   		struct drm_i915_gem_request *req;
>
> -		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
> -		if (ret)
> -			return ret;
> +		req = i915_gem_request_alloc(ring, NULL);
> +		if (IS_ERR(req))
> +			return PTR_ERR(req);
>
>   		ret = intel_ring_begin(req, 2);
>   		if (ret) {
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c6dd4db..c2b000a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2260,9 +2260,9 @@  struct drm_i915_gem_request {
 
 };
 
-int i915_gem_request_alloc(struct intel_engine_cs *ring,
-			   struct intel_context *ctx,
-			   struct drm_i915_gem_request **req_out);
+struct drm_i915_gem_request * __must_check
+i915_gem_request_alloc(struct intel_engine_cs *engine,
+		       struct intel_context *ctx);
 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,
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6c60e04..c908ed1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2688,9 +2688,10 @@  void i915_gem_request_free(struct kref *req_ref)
 	kmem_cache_free(req->i915->requests, req);
 }
 
-int i915_gem_request_alloc(struct intel_engine_cs *ring,
-			   struct intel_context *ctx,
-			   struct drm_i915_gem_request **req_out)
+static inline int
+__i915_gem_request_alloc(struct intel_engine_cs *ring,
+			 struct intel_context *ctx,
+			 struct drm_i915_gem_request **req_out)
 {
 	struct drm_i915_private *dev_priv = to_i915(ring->dev);
 	struct drm_i915_gem_request *req;
@@ -2753,6 +2754,31 @@  err:
 	return ret;
 }
 
+/**
+ * i915_gem_request_alloc - allocate a request structure
+ *
+ * @engine: engine that we wish to issue the request on.
+ * @ctx: context that the request will be associated with.
+ *       This can be NULL if the request is not directly related to
+ *       any specific user context, in which case this function will
+ *       choose an appropriate context to use.
+ *
+ * Returns a pointer to the allocated request if successful,
+ * or an error code if not.
+ */
+struct drm_i915_gem_request *
+i915_gem_request_alloc(struct intel_engine_cs *engine,
+		       struct intel_context *ctx)
+{
+	struct drm_i915_gem_request *req;
+	int err;
+
+	if (ctx == NULL)
+		ctx = engine->default_context;
+	err = __i915_gem_request_alloc(engine, ctx, &req);
+	return err ? ERR_PTR(err) : req;
+}
+
 void i915_gem_request_cancel(struct drm_i915_gem_request *req)
 {
 	intel_ring_reserved_space_cancel(req->ringbuf);
@@ -3170,9 +3196,13 @@  __i915_gem_object_sync(struct drm_i915_gem_object *obj,
 			return 0;
 
 		if (*to_req == NULL) {
-			ret = i915_gem_request_alloc(to, to->default_context, to_req);
-			if (ret)
-				return ret;
+			struct drm_i915_gem_request *req;
+
+			req = i915_gem_request_alloc(to, NULL);
+			if (IS_ERR(req))
+				return PTR_ERR(req);
+
+			*to_req = req;
 		}
 
 		trace_i915_gem_ring_sync_to(*to_req, from, from_req);
@@ -3372,9 +3402,9 @@  int i915_gpu_idle(struct drm_device *dev)
 		if (!i915.enable_execlists) {
 			struct drm_i915_gem_request *req;
 
-			ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-			if (ret)
-				return ret;
+			req = i915_gem_request_alloc(ring, NULL);
+			if (IS_ERR(req))
+				return PTR_ERR(req);
 
 			ret = i915_switch_context(req);
 			if (ret) {
@@ -4869,10 +4899,9 @@  i915_gem_init_hw(struct drm_device *dev)
 	for_each_ring(ring, dev_priv, i) {
 		struct drm_i915_gem_request *req;
 
-		WARN_ON(!ring->default_context);
-
-		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-		if (ret) {
+		req = i915_gem_request_alloc(ring, NULL);
+		if (IS_ERR(req)) {
+			ret = PTR_ERR(req);
 			i915_gem_cleanup_ringbuffer(dev);
 			goto out;
 		}
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index dccb517..dc6caeb 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1381,6 +1381,7 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		       struct drm_i915_gem_exec_object2 *exec)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_request *req = NULL;
 	struct eb_vmas *eb;
 	struct drm_i915_gem_object *batch_obj;
 	struct drm_i915_gem_exec_object2 shadow_exec_entry;
@@ -1602,11 +1603,13 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 		params->batch_obj_vm_offset = i915_gem_obj_offset(batch_obj, vm);
 
 	/* Allocate a request for this batch buffer nice and early. */
-	ret = i915_gem_request_alloc(ring, ctx, &params->request);
-	if (ret)
+	req = i915_gem_request_alloc(ring, ctx);
+	if (IS_ERR(req)) {
+		ret = PTR_ERR(req);
 		goto err_batch_unpin;
+	}
 
-	ret = i915_gem_request_add_to_client(params->request, file);
+	ret = i915_gem_request_add_to_client(req, file);
 	if (ret)
 		goto err_batch_unpin;
 
@@ -1622,6 +1625,7 @@  i915_gem_do_execbuffer(struct drm_device *dev, void *data,
 	params->dispatch_flags          = dispatch_flags;
 	params->batch_obj               = batch_obj;
 	params->ctx                     = ctx;
+	params->request                 = req;
 
 	ret = dev_priv->gt.execbuf_submit(params, args, &eb->vmas);
 
@@ -1645,8 +1649,8 @@  err:
 	 * must be freed again. If it was submitted then it is being tracked
 	 * on the active request list and no clean up is required here.
 	 */
-	if (ret && params->request)
-		i915_gem_request_cancel(params->request);
+	if (ret && req)
+		i915_gem_request_cancel(req);
 
 	mutex_unlock(&dev->struct_mutex);
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ed9ab60..1f8f781 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11700,9 +11700,11 @@  static int intel_crtc_page_flip(struct drm_crtc *crtc,
 					obj->last_write_req);
 	} else {
 		if (!request) {
-			ret = i915_gem_request_alloc(ring, ring->default_context, &request);
-			if (ret)
+			request = i915_gem_request_alloc(ring, NULL);
+			if (IS_ERR(request)) {
+				ret = PTR_ERR(request);
 				goto cleanup_unpin;
+			}
 		}
 
 		ret = dev_priv->display.queue_flip(dev, crtc, fb, obj, request,
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index 8096c6a..8b6542d 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -2510,11 +2510,10 @@  int intel_lr_context_deferred_alloc(struct intel_context *ctx,
 	if (ctx != ring->default_context && ring->init_context) {
 		struct drm_i915_gem_request *req;
 
-		ret = i915_gem_request_alloc(ring,
-			ctx, &req);
-		if (ret) {
-			DRM_ERROR("ring create req: %d\n",
-				ret);
+		req = i915_gem_request_alloc(ring, ctx);
+		if (IS_ERR(req)) {
+			ret = PTR_ERR(req);
+			DRM_ERROR("ring create req: %d\n", ret);
 			goto error_ringbuf;
 		}
 
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 76f1980..9168413 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -240,9 +240,9 @@  static int intel_overlay_on(struct intel_overlay *overlay)
 	WARN_ON(overlay->active);
 	WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
 
-	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-	if (ret)
-		return ret;
+	req = i915_gem_request_alloc(ring, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	ret = intel_ring_begin(req, 4);
 	if (ret) {
@@ -283,9 +283,9 @@  static int intel_overlay_continue(struct intel_overlay *overlay,
 	if (tmp & (1 << 17))
 		DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
 
-	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-	if (ret)
-		return ret;
+	req = i915_gem_request_alloc(ring, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	ret = intel_ring_begin(req, 2);
 	if (ret) {
@@ -349,9 +349,9 @@  static int intel_overlay_off(struct intel_overlay *overlay)
 	 * of the hw. Do it in both cases */
 	flip_addr |= OFC_UPDATE;
 
-	ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-	if (ret)
-		return ret;
+	req = i915_gem_request_alloc(ring, NULL);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	ret = intel_ring_begin(req, 6);
 	if (ret) {
@@ -423,9 +423,9 @@  static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 		/* synchronous slowpath */
 		struct drm_i915_gem_request *req;
 
-		ret = i915_gem_request_alloc(ring, ring->default_context, &req);
-		if (ret)
-			return ret;
+		req = i915_gem_request_alloc(ring, NULL);
+		if (IS_ERR(req))
+			return PTR_ERR(req);
 
 		ret = intel_ring_begin(req, 2);
 		if (ret) {