Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad7ad48e authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2019-03-12' of...

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

 into drm-next

- HDCP state handling in ddi_update_pipe
- Protect i915_active iterators from the shrinker
- Reacquire priolist cache after dropping the engine lock
- (Selftest) Always free spinner on __sseu_prepare error
- Acquire breadcrumb ref before canceling
- Fix atomic state leak on HDMI link reset
- Relax mmap VMA check

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

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190312205551.GA7701@intel.com
parents 74cd45fa ca22f32a
Loading
Loading
Loading
Loading
+25 −11
Original line number Diff line number Diff line
@@ -163,17 +163,25 @@ int i915_active_ref(struct i915_active *ref,
		    struct i915_request *rq)
{
	struct i915_active_request *active;
	int err = 0;

	/* Prevent reaping in case we malloc/wait while building the tree */
	i915_active_acquire(ref);

	active = active_instance(ref, timeline);
	if (IS_ERR(active))
		return PTR_ERR(active);
	if (IS_ERR(active)) {
		err = PTR_ERR(active);
		goto out;
	}

	if (!i915_active_request_isset(active))
		ref->count++;
	__i915_active_request_set(active, rq);

	GEM_BUG_ON(!ref->count);
	return 0;
out:
	i915_active_release(ref);
	return err;
}

bool i915_active_acquire(struct i915_active *ref)
@@ -223,19 +231,25 @@ int i915_request_await_active_request(struct i915_request *rq,
int i915_request_await_active(struct i915_request *rq, struct i915_active *ref)
{
	struct active_node *it, *n;
	int ret;
	int err = 0;

	ret = i915_request_await_active_request(rq, &ref->last);
	if (ret)
		return ret;
	/* await allocates and so we need to avoid hitting the shrinker */
	if (i915_active_acquire(ref))
		goto out; /* was idle */

	err = i915_request_await_active_request(rq, &ref->last);
	if (err)
		goto out;

	rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
		ret = i915_request_await_active_request(rq, &it->base);
		if (ret)
			return ret;
		err = i915_request_await_active_request(rq, &it->base);
		if (err)
			goto out;
	}

	return 0;
out:
	i915_active_release(ref);
	return err;
}

#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+2 −1
Original line number Diff line number Diff line
@@ -1688,7 +1688,8 @@ __vma_matches(struct vm_area_struct *vma, struct file *filp,
	if (vma->vm_file != filp)
		return false;

	return vma->vm_start == addr && (vma->vm_end - vma->vm_start) == size;
	return vma->vm_start == addr &&
	       (vma->vm_end - vma->vm_start) == PAGE_ALIGN(size);
}

/**
+17 −10
Original line number Diff line number Diff line
@@ -223,8 +223,14 @@ i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio)
	return &p->requests[idx];
}

struct sched_cache {
	struct list_head *priolist;
};

static struct intel_engine_cs *
sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
sched_lock_engine(const struct i915_sched_node *node,
		  struct intel_engine_cs *locked,
		  struct sched_cache *cache)
{
	struct intel_engine_cs *engine = node_to_request(node)->engine;

@@ -232,6 +238,7 @@ sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)

	if (engine != locked) {
		spin_unlock(&locked->timeline.lock);
		memset(cache, 0, sizeof(*cache));
		spin_lock(&engine->timeline.lock);
	}

@@ -253,11 +260,11 @@ static bool inflight(const struct i915_request *rq,
static void __i915_schedule(struct i915_request *rq,
			    const struct i915_sched_attr *attr)
{
	struct list_head *uninitialized_var(pl);
	struct intel_engine_cs *engine, *last;
	struct intel_engine_cs *engine;
	struct i915_dependency *dep, *p;
	struct i915_dependency stack;
	const int prio = attr->priority;
	struct sched_cache cache;
	LIST_HEAD(dfs);

	/* Needed in order to use the temporary link inside i915_dependency */
@@ -328,7 +335,7 @@ static void __i915_schedule(struct i915_request *rq,
		__list_del_entry(&stack.dfs_link);
	}

	last = NULL;
	memset(&cache, 0, sizeof(cache));
	engine = rq->engine;
	spin_lock_irq(&engine->timeline.lock);

@@ -338,7 +345,7 @@ static void __i915_schedule(struct i915_request *rq,

		INIT_LIST_HEAD(&dep->dfs_link);

		engine = sched_lock_engine(node, engine);
		engine = sched_lock_engine(node, engine, &cache);
		lockdep_assert_held(&engine->timeline.lock);

		/* Recheck after acquiring the engine->timeline.lock */
@@ -347,11 +354,11 @@ static void __i915_schedule(struct i915_request *rq,

		node->attr.priority = prio;
		if (!list_empty(&node->link)) {
			if (last != engine) {
				pl = i915_sched_lookup_priolist(engine, prio);
				last = engine;
			}
			list_move_tail(&node->link, pl);
			if (!cache.priolist)
				cache.priolist =
					i915_sched_lookup_priolist(engine,
								   prio);
			list_move_tail(&node->link, cache.priolist);
		} else {
			/*
			 * If the request is not in the priolist queue because
+8 −10
Original line number Diff line number Diff line
@@ -106,16 +106,6 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)

			GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
					     &rq->fence.flags));
			clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);

			/*
			 * We may race with direct invocation of
			 * dma_fence_signal(), e.g. i915_request_retire(),
			 * in which case we can skip processing it ourselves.
			 */
			if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
				     &rq->fence.flags))
				continue;

			/*
			 * Queue for execution after dropping the signaling
@@ -123,6 +113,14 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
			 * more signalers to the same context or engine.
			 */
			i915_request_get(rq);

			/*
			 * We may race with direct invocation of
			 * dma_fence_signal(), e.g. i915_request_retire(),
			 * so we need to acquire our reference to the request
			 * before we cancel the breadcrumb.
			 */
			clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
			list_add_tail(&rq->signal_link, &signal);
		}

+8 −6
Original line number Diff line number Diff line
@@ -3568,6 +3568,13 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
{
	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);

	if (conn_state->content_protection ==
	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
		intel_hdcp_enable(to_intel_connector(conn_state->connector));
	else if (conn_state->content_protection ==
		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
		intel_hdcp_disable(to_intel_connector(conn_state->connector));
}

static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
@@ -3962,11 +3969,6 @@ static int modeset_pipe(struct drm_crtc *crtc,
		goto out;

	ret = drm_atomic_commit(state);
	if (ret)
		goto out;

	return 0;

out:
	drm_atomic_state_put(state);

Loading