Commit 038a0a8d authored by Jani Nikula's avatar Jani Nikula
Browse files

Merge tag 'gvt-fixes-2019-01-09' of https://github.com/intel/gvt-linux into drm-intel-fixes



gvt-fixes-2019-01-09

- Fix one race issue between pre-scan of guest workload with submission

Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
From: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190109050151.GL11631@zhen-hp.sh.intel.com
parents bfeffd15 f0e99437
Loading
Loading
Loading
Loading
+42 −22
Original line number Original line Diff line number Diff line
@@ -356,6 +356,33 @@ static int set_context_ppgtt_from_shadow(struct intel_vgpu_workload *workload,
	return 0;
	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
 * intel_gvt_scan_and_shadow_workload - audit the workload by scanning and
 * shadow it as well, include ringbuffer,wa_ctx and ctx.
 * 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 drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
	struct intel_engine_cs *engine = dev_priv->engine[workload->ring_id];
	struct intel_context *ce;
	struct intel_context *ce;
	struct i915_request *rq;
	int ret;
	int ret;


	lockdep_assert_held(&dev_priv->drm.struct_mutex);
	lockdep_assert_held(&dev_priv->drm.struct_mutex);


	if (workload->req)
	if (workload->shadow)
		return 0;
		return 0;


	ret = set_context_ppgtt_from_shadow(workload, shadow_ctx);
	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;
			goto err_shadow;
	}
	}


	rq = i915_request_alloc(engine, shadow_ctx);
	workload->shadow = true;
	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;

	return 0;
	return 0;
err_req:
	rq = fetch_and_zero(&workload->req);
	i915_request_put(rq);
err_shadow:
err_shadow:
	release_shadow_wa_ctx(&workload->wa_ctx);
	release_shadow_wa_ctx(&workload->wa_ctx);
err_unpin:
err_unpin:
@@ -671,23 +683,31 @@ static int dispatch_workload(struct intel_vgpu_workload *workload)
	mutex_lock(&vgpu->vgpu_lock);
	mutex_lock(&vgpu->vgpu_lock);
	mutex_lock(&dev_priv->drm.struct_mutex);
	mutex_lock(&dev_priv->drm.struct_mutex);


	ret = intel_gvt_workload_req_alloc(workload);
	if (ret)
		goto err_req;

	ret = intel_gvt_scan_and_shadow_workload(workload);
	ret = intel_gvt_scan_and_shadow_workload(workload);
	if (ret)
	if (ret)
		goto out;
		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:
out:
	if (ret)
		workload->status = ret;

	if (!IS_ERR_OR_NULL(workload->req)) {
	if (!IS_ERR_OR_NULL(workload->req)) {
		gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
		gvt_dbg_sched("ring id %d submit workload to i915 %p\n",
				ring_id, workload->req);
				ring_id, workload->req);
		i915_request_add(workload->req);
		i915_request_add(workload->req);
		workload->dispatched = true;
		workload->dispatched = true;
	}
	}

err_req:
	if (ret)
		workload->status = ret;
	mutex_unlock(&dev_priv->drm.struct_mutex);
	mutex_unlock(&dev_priv->drm.struct_mutex);
	mutex_unlock(&vgpu->vgpu_lock);
	mutex_unlock(&vgpu->vgpu_lock);
	return ret;
	return ret;
+1 −0
Original line number Original line Diff line number Diff line
@@ -83,6 +83,7 @@ struct intel_vgpu_workload {
	struct i915_request *req;
	struct i915_request *req;
	/* if this workload has been dispatched to i915? */
	/* if this workload has been dispatched to i915? */
	bool dispatched;
	bool dispatched;
	bool shadow;      /* if workload has done shadow of guest request */
	int status;
	int status;


	struct intel_vgpu_mm *shadow_mm;
	struct intel_vgpu_mm *shadow_mm;