Commit 023941cf authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2019-09-11' of...

Merge tag 'drm-intel-next-fixes-2019-09-11' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-next

Few fixes on GGTT and PPGTT around pin, locks, fence and vgpu.

This also includes GVT fixes with two recent fixes:
one for recent guest hang regression and another for guest reset fix.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190911233309.GA18449@intel.com
parents ad49e38e 6e5c5272
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf)
	vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
				       PIN_MAPPABLE |
				       PIN_NONBLOCK /* NOWARN */ |
				       PIN_NOSEARCH);
				       PIN_NOEVICT);
	if (IS_ERR(vma)) {
		/* Use a partial view if it is bigger than available space */
		struct i915_ggtt_view view =
+18 −10
Original line number Diff line number Diff line
@@ -39,27 +39,32 @@ static int __engine_unpark(struct intel_wakeref *wf)

#if IS_ENABLED(CONFIG_LOCKDEP)

static inline void __timeline_mark_lock(struct intel_context *ce)
static inline unsigned long __timeline_mark_lock(struct intel_context *ce)
{
	unsigned long flags;

	local_irq_save(flags);
	mutex_acquire(&ce->timeline->mutex.dep_map, 2, 0, _THIS_IP_);
	local_irq_restore(flags);

	return flags;
}

static inline void __timeline_mark_unlock(struct intel_context *ce)
static inline void __timeline_mark_unlock(struct intel_context *ce,
					  unsigned long flags)
{
	mutex_release(&ce->timeline->mutex.dep_map, 0, _THIS_IP_);
	local_irq_restore(flags);
}

#else

static inline void __timeline_mark_lock(struct intel_context *ce)
static inline unsigned long __timeline_mark_lock(struct intel_context *ce)
{
	return 0;
}

static inline void __timeline_mark_unlock(struct intel_context *ce)
static inline void __timeline_mark_unlock(struct intel_context *ce,
					  unsigned long flags)
{
}

@@ -68,6 +73,8 @@ static inline void __timeline_mark_unlock(struct intel_context *ce)
static bool switch_to_kernel_context(struct intel_engine_cs *engine)
{
	struct i915_request *rq;
	unsigned long flags;
	bool result = true;

	/* Already inside the kernel context, safe to power down. */
	if (engine->wakeref_serial == engine->serial)
@@ -89,12 +96,12 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
	 * retiring the last request, thus all rings should be empty and
	 * all timelines idle.
	 */
	__timeline_mark_lock(engine->kernel_context);
	flags = __timeline_mark_lock(engine->kernel_context);

	rq = __i915_request_create(engine->kernel_context, GFP_NOWAIT);
	if (IS_ERR(rq))
		/* Context switch failed, hope for the best! Maybe reset? */
		return true;
		goto out_unlock;

	intel_timeline_enter(rq->timeline);

@@ -110,9 +117,10 @@ static bool switch_to_kernel_context(struct intel_engine_cs *engine)
	__intel_wakeref_defer_park(&engine->wakeref);
	__i915_request_queue(rq, NULL);

	__timeline_mark_unlock(engine->kernel_context);

	return false;
	result = false;
out_unlock:
	__timeline_mark_unlock(engine->kernel_context, flags);
	return result;
}

static int __engine_park(struct intel_wakeref *wf)
+5 −4
Original line number Diff line number Diff line
@@ -792,6 +792,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
{
	struct intel_gt_timelines *timelines = &gt->timelines;
	struct intel_timeline *tl;
	unsigned long flags;

	if (!test_bit(I915_WEDGED, &gt->reset.flags))
		return true;
@@ -811,7 +812,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
	 *
	 * No more can be submitted until we reset the wedged bit.
	 */
	spin_lock(&timelines->lock);
	spin_lock_irqsave(&timelines->lock, flags);
	list_for_each_entry(tl, &timelines->active_list, link) {
		struct i915_request *rq;

@@ -819,7 +820,7 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
		if (!rq)
			continue;

		spin_unlock(&timelines->lock);
		spin_unlock_irqrestore(&timelines->lock, flags);

		/*
		 * All internal dependencies (i915_requests) will have
@@ -832,10 +833,10 @@ static bool __intel_gt_unset_wedged(struct intel_gt *gt)
		i915_request_put(rq);

		/* Restart iteration after droping lock */
		spin_lock(&timelines->lock);
		spin_lock_irqsave(&timelines->lock, flags);
		tl = list_entry(&timelines->active_list, typeof(*tl), link);
	}
	spin_unlock(&timelines->lock);
	spin_unlock_irqrestore(&timelines->lock, flags);

	intel_gt_sanitize(gt, false);

+6 −4
Original line number Diff line number Diff line
@@ -337,6 +337,7 @@ int intel_timeline_pin(struct intel_timeline *tl)
void intel_timeline_enter(struct intel_timeline *tl)
{
	struct intel_gt_timelines *timelines = &tl->gt->timelines;
	unsigned long flags;

	lockdep_assert_held(&tl->mutex);

@@ -345,14 +346,15 @@ void intel_timeline_enter(struct intel_timeline *tl)
		return;
	GEM_BUG_ON(!tl->active_count); /* overflow? */

	spin_lock(&timelines->lock);
	spin_lock_irqsave(&timelines->lock, flags);
	list_add(&tl->link, &timelines->active_list);
	spin_unlock(&timelines->lock);
	spin_unlock_irqrestore(&timelines->lock, flags);
}

void intel_timeline_exit(struct intel_timeline *tl)
{
	struct intel_gt_timelines *timelines = &tl->gt->timelines;
	unsigned long flags;

	lockdep_assert_held(&tl->mutex);

@@ -360,9 +362,9 @@ void intel_timeline_exit(struct intel_timeline *tl)
	if (--tl->active_count)
		return;

	spin_lock(&timelines->lock);
	spin_lock_irqsave(&timelines->lock, flags);
	list_del(&tl->link);
	spin_unlock(&timelines->lock);
	spin_unlock_irqrestore(&timelines->lock, flags);

	/*
	 * Since this timeline is idle, all bariers upon which we were waiting
+32 −13
Original line number Diff line number Diff line
@@ -568,6 +568,16 @@ static int prepare_shadow_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
	return 0;
}

static void update_vreg_in_ctx(struct intel_vgpu_workload *workload)
{
	struct intel_vgpu *vgpu = workload->vgpu;
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	u32 ring_base;

	ring_base = dev_priv->engine[workload->ring_id]->mmio_base;
	vgpu_vreg_t(vgpu, RING_START(ring_base)) = workload->rb_start;
}

static void release_shadow_batch_buffer(struct intel_vgpu_workload *workload)
{
	struct intel_vgpu *vgpu = workload->vgpu;
@@ -1016,6 +1026,13 @@ static int workload_thread(void *priv)
		if (need_force_wake)
			intel_uncore_forcewake_get(&gvt->dev_priv->uncore,
					FORCEWAKE_ALL);
		/*
		 * Update the vReg of the vGPU which submitted this
		 * workload. The vGPU may use these registers for checking
		 * the context state. The value comes from GPU commands
		 * in this workload.
		 */
		update_vreg_in_ctx(workload);

		ret = dispatch_workload(workload);

@@ -1438,9 +1455,6 @@ static int prepare_mm(struct intel_vgpu_workload *workload)
#define same_context(a, b) (((a)->context_id == (b)->context_id) && \
		((a)->lrca == (b)->lrca))

#define get_last_workload(q) \
	(list_empty(q) ? NULL : container_of(q->prev, \
	struct intel_vgpu_workload, list))
/**
 * intel_vgpu_create_workload - create a vGPU workload
 * @vgpu: a vGPU
@@ -1460,7 +1474,7 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
{
	struct intel_vgpu_submission *s = &vgpu->submission;
	struct list_head *q = workload_q_head(vgpu, ring_id);
	struct intel_vgpu_workload *last_workload = get_last_workload(q);
	struct intel_vgpu_workload *last_workload = NULL;
	struct intel_vgpu_workload *workload = NULL;
	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
	u64 ring_context_gpa;
@@ -1486,8 +1500,11 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
	head &= RB_HEAD_OFF_MASK;
	tail &= RB_TAIL_OFF_MASK;

	if (last_workload && same_context(&last_workload->ctx_desc, desc)) {
		gvt_dbg_el("ring id %d cur workload == last\n", ring_id);
	list_for_each_entry_reverse(last_workload, q, list) {

		if (same_context(&last_workload->ctx_desc, desc)) {
			gvt_dbg_el("ring id %d cur workload == last\n",
					ring_id);
			gvt_dbg_el("ctx head %x real head %lx\n", head,
					last_workload->rb_tail);
			/*
@@ -1495,6 +1512,8 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu, int ring_id,
			 * as it might not be updated at this time
			 */
			head = last_workload->rb_tail;
			break;
		}
	}

	gvt_dbg_el("ring id %d begin a new workload\n", ring_id);
Loading