[PATCH] drm/i915/gvt: Fix workload request allocation before request add

Yang, Bin bin.yang at intel.com
Tue Dec 25 06:24:41 UTC 2018


On Tue, 2018-12-25 at 10:22 +0800, Zhenyu Wang wrote:
> In commit 6bb2a2af8b1b ("drm/i915/gvt: Fix crash after request->hw_context change"),
> forgot to handle workload scan path in ELSP handler case which was to
> optimize scanning earlier instead of in gvt submission thread, so request
> alloc and add was splitted then which is against right process.
> 
> This trys to do a partial revert of that commit which still has workload
> request alloc helper and make sure shadow state population is handled after
> request alloc for target state buffer.
> 
> Fixes: 6bb2a2af8b1b ("drm/i915/gvt: Fix crash after request->hw_context change")
> Cc: Bin Yang <bin.yang at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Signed-off-by: Zhenyu Wang <zhenyuw at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/gvt/scheduler.c | 65 ++++++++++++++++++++--------
>  drivers/gpu/drm/i915/gvt/scheduler.h |  1 +
>  2 files changed, 47 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
> index 1ad8c5e1455d..21633154086e 100644
> --- a/drivers/gpu/drm/i915/gvt/scheduler.c
> +++ b/drivers/gpu/drm/i915/gvt/scheduler.c
> @@ -356,6 +356,33 @@ static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
>  	return 0;
>  }
>  
> +static int
> +intel_gvt_workload_req_alloc(struct intel_vgpu_workload *workload)
> +{
> +	struct intel_vgpu *vgpu = workload->vgpu;
> +	struct intel_vgpu_submission *s = &vgpu->submission;
> +	struct i915_gem_context *shadow_ctx = s->shadow_ctx;
> +	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
> +	struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
> +	struct i915_request *rq;
> +	int ret = 0;
> +
> +	lockdep_assert_held(&dev_priv->drm.struct_mutex);
> +
> +	if (workload->req)
> +		goto out;
> +
> +	rq = i915_request_alloc(engine, shadow_ctx);
> +	if (IS_ERR(rq)) {
> +		gvt_vgpu_err("fail to allocate gem request\n");
> +		ret = PTR_ERR(rq);
> +		goto out;
> +	}
> +	workload->req = i915_request_get(rq);
> +out:
> +	return ret;
> +}
> +
>  /**
>   * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and
>   * shadow it as well, include ringbuffer,wa_ctx and ctx.
> @@ -372,12 +399,11 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
>  	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
>  	struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
>  	struct intel_context *ce;
> -	struct i915_request *rq;
>  	int ret;
>  
>  	lockdep_assert_held(&dev_priv->drm.struct_mutex);
>  
> -	if (workload->req)
> +	if (workload->shadow)
>  		return 0;
>  
>  	ret = set_context_ppgtt_from_shadow(workload, shadow_ctx);
> @@ -417,22 +443,8 @@ int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload)
>  			goto err_shadow;
>  	}
>  
> -	rq = i915_request_alloc(engine, shadow_ctx);
> -	if (IS_ERR(rq)) {
> -		gvt_vgpu_err("fail to allocate gem request\n");
> -		ret = PTR_ERR(rq);
> -		goto err_shadow;
> -	}
> -	workload->req = i915_request_get(rq);
> -
> -	ret = populate_shadow_context(workload);
> -	if (ret)
> -		goto err_req;
> -
> +	workload->shadow = true;
>  	return 0;
> -err_req:
> -	rq = fetch_and_zero(&workload->req);
> -	i915_request_put(rq);
>  err_shadow:
>  	release_shadow_wa_ctx(&workload->wa_ctx);
>  err_unpin:
> @@ -671,15 +683,30 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
>  	mutex_lock(&vgpu->vgpu_lock);
>  	mutex_lock(&dev_priv->drm.struct_mutex);
>  
> +	ret = intel_gvt_workload_req_alloc(workload);
> +	if (ret)
> +		goto out;
> +
>  	ret = intel_gvt_scan_and_shadow_workload(workload);
>  	if (ret)
>  		goto out;
>  
> -	ret = prepare_workload(workload);
> +	ret = populate_shadow_context(workload);
> +	if (ret) {
> +		release_shadow_wa_ctx(&workload->wa_ctx);
> +		goto out;
> +	}
>  
> +	ret = prepare_workload(workload);
>  out:
> -	if (ret)
> +	if (ret) {
> +		if (workload->req) {
> +			struct i915_request *rq;
> +			rq = fetch_and_zero(&workload->req);
> +			i915_request_put(rq);
> +		}
>  		workload->status = ret;
> +	}
>  
>  	if (!IS_ERR_OR_NULL(workload->req)) {
>  		gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
> diff --git a/drivers/gpu/drm/i915/gvt/scheduler.h b/drivers/gpu/drm/i915/gvt/scheduler.h
> index ca5529d0e48e..2065cba59aab 100644
> --- a/drivers/gpu/drm/i915/gvt/scheduler.h
> +++ b/drivers/gpu/drm/i915/gvt/scheduler.h
> @@ -83,6 +83,7 @@ struct intel_vgpu_workload {
>  	struct i915_request *req;
>  	/* if this workload has been dispatched to i915? */
>  	bool dispatched;
> +	bool shadow;      /* if workload has done shadow of guest request */
>  	int status;
>  
>  	struct intel_vgpu_mm *shadow_mm;


Tested on Apollo Lake with Clearlinux + ACRN, works fine.

Tested-by: Bin Yang <bin.yang at intel.com>

thanks


More information about the intel-gvt-dev mailing list