Skip to content

Commit ad7ad48

Browse files
committed
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: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190312205551.GA7701@intel.com
2 parents 74cd45f + ca22f32 commit ad7ad48

File tree

6 files changed

+94
-73
lines changed

6 files changed

+94
-73
lines changed

drivers/gpu/drm/i915/i915_active.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,17 +163,25 @@ int i915_active_ref(struct i915_active *ref,
163163
struct i915_request *rq)
164164
{
165165
struct i915_active_request *active;
166+
int err = 0;
167+
168+
/* Prevent reaping in case we malloc/wait while building the tree */
169+
i915_active_acquire(ref);
166170

167171
active = active_instance(ref, timeline);
168-
if (IS_ERR(active))
169-
return PTR_ERR(active);
172+
if (IS_ERR(active)) {
173+
err = PTR_ERR(active);
174+
goto out;
175+
}
170176

171177
if (!i915_active_request_isset(active))
172178
ref->count++;
173179
__i915_active_request_set(active, rq);
174180

175181
GEM_BUG_ON(!ref->count);
176-
return 0;
182+
out:
183+
i915_active_release(ref);
184+
return err;
177185
}
178186

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

228-
ret = i915_request_await_active_request(rq, &ref->last);
229-
if (ret)
230-
return ret;
236+
/* await allocates and so we need to avoid hitting the shrinker */
237+
if (i915_active_acquire(ref))
238+
goto out; /* was idle */
239+
240+
err = i915_request_await_active_request(rq, &ref->last);
241+
if (err)
242+
goto out;
231243

232244
rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
233-
ret = i915_request_await_active_request(rq, &it->base);
234-
if (ret)
235-
return ret;
245+
err = i915_request_await_active_request(rq, &it->base);
246+
if (err)
247+
goto out;
236248
}
237249

238-
return 0;
250+
out:
251+
i915_active_release(ref);
252+
return err;
239253
}
240254

241255
#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)

drivers/gpu/drm/i915/i915_gem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1688,7 +1688,8 @@ __vma_matches(struct vm_area_struct *vma, struct file *filp,
16881688
if (vma->vm_file != filp)
16891689
return false;
16901690

1691-
return vma->vm_start == addr && (vma->vm_end - vma->vm_start) == size;
1691+
return vma->vm_start == addr &&
1692+
(vma->vm_end - vma->vm_start) == PAGE_ALIGN(size);
16921693
}
16931694

16941695
/**

drivers/gpu/drm/i915/i915_scheduler.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,22 @@ i915_sched_lookup_priolist(struct intel_engine_cs *engine, int prio)
223223
return &p->requests[idx];
224224
}
225225

226+
struct sched_cache {
227+
struct list_head *priolist;
228+
};
229+
226230
static struct intel_engine_cs *
227-
sched_lock_engine(struct i915_sched_node *node, struct intel_engine_cs *locked)
231+
sched_lock_engine(const struct i915_sched_node *node,
232+
struct intel_engine_cs *locked,
233+
struct sched_cache *cache)
228234
{
229235
struct intel_engine_cs *engine = node_to_request(node)->engine;
230236

231237
GEM_BUG_ON(!locked);
232238

233239
if (engine != locked) {
234240
spin_unlock(&locked->timeline.lock);
241+
memset(cache, 0, sizeof(*cache));
235242
spin_lock(&engine->timeline.lock);
236243
}
237244

@@ -253,11 +260,11 @@ static bool inflight(const struct i915_request *rq,
253260
static void __i915_schedule(struct i915_request *rq,
254261
const struct i915_sched_attr *attr)
255262
{
256-
struct list_head *uninitialized_var(pl);
257-
struct intel_engine_cs *engine, *last;
263+
struct intel_engine_cs *engine;
258264
struct i915_dependency *dep, *p;
259265
struct i915_dependency stack;
260266
const int prio = attr->priority;
267+
struct sched_cache cache;
261268
LIST_HEAD(dfs);
262269

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

331-
last = NULL;
338+
memset(&cache, 0, sizeof(cache));
332339
engine = rq->engine;
333340
spin_lock_irq(&engine->timeline.lock);
334341

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

339346
INIT_LIST_HEAD(&dep->dfs_link);
340347

341-
engine = sched_lock_engine(node, engine);
348+
engine = sched_lock_engine(node, engine, &cache);
342349
lockdep_assert_held(&engine->timeline.lock);
343350

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

348355
node->attr.priority = prio;
349356
if (!list_empty(&node->link)) {
350-
if (last != engine) {
351-
pl = i915_sched_lookup_priolist(engine, prio);
352-
last = engine;
353-
}
354-
list_move_tail(&node->link, pl);
357+
if (!cache.priolist)
358+
cache.priolist =
359+
i915_sched_lookup_priolist(engine,
360+
prio);
361+
list_move_tail(&node->link, cache.priolist);
355362
} else {
356363
/*
357364
* If the request is not in the priolist queue because

drivers/gpu/drm/i915/intel_breadcrumbs.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,23 +106,21 @@ bool intel_engine_breadcrumbs_irq(struct intel_engine_cs *engine)
106106

107107
GEM_BUG_ON(!test_bit(I915_FENCE_FLAG_SIGNAL,
108108
&rq->fence.flags));
109-
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
110-
111-
/*
112-
* We may race with direct invocation of
113-
* dma_fence_signal(), e.g. i915_request_retire(),
114-
* in which case we can skip processing it ourselves.
115-
*/
116-
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
117-
&rq->fence.flags))
118-
continue;
119109

120110
/*
121111
* Queue for execution after dropping the signaling
122112
* spinlock as the callback chain may end up adding
123113
* more signalers to the same context or engine.
124114
*/
125115
i915_request_get(rq);
116+
117+
/*
118+
* We may race with direct invocation of
119+
* dma_fence_signal(), e.g. i915_request_retire(),
120+
* so we need to acquire our reference to the request
121+
* before we cancel the breadcrumb.
122+
*/
123+
clear_bit(I915_FENCE_FLAG_SIGNAL, &rq->fence.flags);
126124
list_add_tail(&rq->signal_link, &signal);
127125
}
128126

drivers/gpu/drm/i915/intel_ddi.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,6 +3568,13 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
35683568
{
35693569
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
35703570
intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
3571+
3572+
if (conn_state->content_protection ==
3573+
DRM_MODE_CONTENT_PROTECTION_DESIRED)
3574+
intel_hdcp_enable(to_intel_connector(conn_state->connector));
3575+
else if (conn_state->content_protection ==
3576+
DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
3577+
intel_hdcp_disable(to_intel_connector(conn_state->connector));
35713578
}
35723579

35733580
static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
@@ -3962,12 +3969,7 @@ static int modeset_pipe(struct drm_crtc *crtc,
39623969
goto out;
39633970

39643971
ret = drm_atomic_commit(state);
3965-
if (ret)
3966-
goto out;
3967-
3968-
return 0;
3969-
3970-
out:
3972+
out:
39713973
drm_atomic_state_put(state);
39723974

39733975
return ret;

drivers/gpu/drm/i915/selftests/i915_gem_context.c

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -710,47 +710,45 @@ __sseu_prepare(struct drm_i915_private *i915,
710710
unsigned int flags,
711711
struct i915_gem_context *ctx,
712712
struct intel_engine_cs *engine,
713-
struct igt_spinner **spin_out)
713+
struct igt_spinner **spin)
714714
{
715-
int ret = 0;
716-
717-
if (flags & (TEST_BUSY | TEST_RESET)) {
718-
struct igt_spinner *spin;
719-
struct i915_request *rq;
715+
struct i915_request *rq;
716+
int ret;
720717

721-
spin = kzalloc(sizeof(*spin), GFP_KERNEL);
722-
if (!spin) {
723-
ret = -ENOMEM;
724-
goto out;
725-
}
718+
*spin = NULL;
719+
if (!(flags & (TEST_BUSY | TEST_RESET)))
720+
return 0;
726721

727-
ret = igt_spinner_init(spin, i915);
728-
if (ret)
729-
return ret;
722+
*spin = kzalloc(sizeof(**spin), GFP_KERNEL);
723+
if (!*spin)
724+
return -ENOMEM;
730725

731-
rq = igt_spinner_create_request(spin, ctx, engine, MI_NOOP);
732-
if (IS_ERR(rq)) {
733-
ret = PTR_ERR(rq);
734-
igt_spinner_fini(spin);
735-
kfree(spin);
736-
goto out;
737-
}
726+
ret = igt_spinner_init(*spin, i915);
727+
if (ret)
728+
goto err_free;
738729

739-
i915_request_add(rq);
730+
rq = igt_spinner_create_request(*spin, ctx, engine, MI_NOOP);
731+
if (IS_ERR(rq)) {
732+
ret = PTR_ERR(rq);
733+
goto err_fini;
734+
}
740735

741-
if (!igt_wait_for_spinner(spin, rq)) {
742-
pr_err("%s: Spinner failed to start!\n", name);
743-
igt_spinner_end(spin);
744-
igt_spinner_fini(spin);
745-
kfree(spin);
746-
ret = -ETIMEDOUT;
747-
goto out;
748-
}
736+
i915_request_add(rq);
749737

750-
*spin_out = spin;
738+
if (!igt_wait_for_spinner(*spin, rq)) {
739+
pr_err("%s: Spinner failed to start!\n", name);
740+
ret = -ETIMEDOUT;
741+
goto err_end;
751742
}
752743

753-
out:
744+
return 0;
745+
746+
err_end:
747+
igt_spinner_end(*spin);
748+
err_fini:
749+
igt_spinner_fini(*spin);
750+
err_free:
751+
kfree(fetch_and_zero(spin));
754752
return ret;
755753
}
756754

@@ -897,22 +895,23 @@ __sseu_test(struct drm_i915_private *i915,
897895

898896
ret = __sseu_prepare(i915, name, flags, ctx, engine, &spin);
899897
if (ret)
900-
goto out;
898+
goto out_context;
901899

902900
ret = __i915_gem_context_reconfigure_sseu(ctx, engine, sseu);
903901
if (ret)
904-
goto out;
902+
goto out_spin;
905903

906904
ret = __sseu_finish(i915, name, flags, ctx, kctx, engine, obj,
907905
hweight32(sseu.slice_mask), spin);
908906

909-
out:
907+
out_spin:
910908
if (spin) {
911909
igt_spinner_end(spin);
912910
igt_spinner_fini(spin);
913911
kfree(spin);
914912
}
915913

914+
out_context:
916915
kernel_context_close(kctx);
917916

918917
return ret;

0 commit comments

Comments
 (0)