Skip to content

Commit 2e49520

Browse files
committed
Merge tag 'drm-intel-next-fixes-2020-10-02' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
Propagated from drm-intel-next-queued: - Fix CRTC state checker (Ville) Propated from drm-intel-gt-next: - Avoid implicit vmpa for highmem on 32b (Chris) - Prevent PAT attriutes for writecombine if CPU doesn't support PAT (Chris) - Clear the buffer pool age before use. (Chris) - Fix error code (Dan) - Break up error capture compression loops (Chris) - Fix uninitialized variable in context_create_request (Maarten) - Check for errors on i915_vm_alloc_pt_stash to avoid NULL dereference (Matt) - Serialize debugfs i915_gem_objects with ctx->mutex (Chris) - Fix a rebase mistake caused during drm-intel-gt-next creation (Chris) - Hold request reference for canceling an active context (Chris) - Heartbeats fixes (Chris) - Use usigned during batch copies (Chris) Signed-off-by: Dave Airlie <[email protected]> From: Rodrigo Vivi <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 083320e + c60b93c commit 2e49520

15 files changed

+175
-114
lines changed

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14304,7 +14304,6 @@ verify_crtc_state(struct intel_crtc *crtc,
1430414304
struct intel_encoder *encoder;
1430514305
struct intel_crtc_state *pipe_config = old_crtc_state;
1430614306
struct drm_atomic_state *state = old_crtc_state->uapi.state;
14307-
bool active;
1430814307

1430914308
__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
1431014309
intel_crtc_free_hw_state(old_crtc_state);
@@ -14314,16 +14313,19 @@ verify_crtc_state(struct intel_crtc *crtc,
1431414313
drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s]\n", crtc->base.base.id,
1431514314
crtc->base.name);
1431614315

14317-
active = dev_priv->display.get_pipe_config(crtc, pipe_config);
14316+
pipe_config->hw.enable = new_crtc_state->hw.enable;
14317+
14318+
pipe_config->hw.active =
14319+
dev_priv->display.get_pipe_config(crtc, pipe_config);
1431814320

1431914321
/* we keep both pipes enabled on 830 */
14320-
if (IS_I830(dev_priv))
14321-
active = new_crtc_state->hw.active;
14322+
if (IS_I830(dev_priv) && pipe_config->hw.active)
14323+
pipe_config->hw.active = new_crtc_state->hw.active;
1432214324

14323-
I915_STATE_WARN(new_crtc_state->hw.active != active,
14325+
I915_STATE_WARN(new_crtc_state->hw.active != pipe_config->hw.active,
1432414326
"crtc active state doesn't match with hw state "
1432514327
"(expected %i, found %i)\n",
14326-
new_crtc_state->hw.active, active);
14328+
new_crtc_state->hw.active, pipe_config->hw.active);
1432714329

1432814330
I915_STATE_WARN(crtc->active != new_crtc_state->hw.active,
1432914331
"transitional active state does not match atomic hw state "
@@ -14332,6 +14334,7 @@ verify_crtc_state(struct intel_crtc *crtc,
1433214334

1433314335
for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
1433414336
enum pipe pipe;
14337+
bool active;
1433514338

1433614339
active = encoder->get_hw_state(encoder, &pipe);
1433714340
I915_STATE_WARN(active != new_crtc_state->hw.active,

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

Lines changed: 29 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -390,24 +390,6 @@ __context_engines_static(const struct i915_gem_context *ctx)
390390
return rcu_dereference_protected(ctx->engines, true);
391391
}
392392

393-
static bool __reset_engine(struct intel_engine_cs *engine)
394-
{
395-
struct intel_gt *gt = engine->gt;
396-
bool success = false;
397-
398-
if (!intel_has_reset_engine(gt))
399-
return false;
400-
401-
if (!test_and_set_bit(I915_RESET_ENGINE + engine->id,
402-
&gt->reset.flags)) {
403-
success = intel_engine_reset(engine, NULL) == 0;
404-
clear_and_wake_up_bit(I915_RESET_ENGINE + engine->id,
405-
&gt->reset.flags);
406-
}
407-
408-
return success;
409-
}
410-
411393
static void __reset_context(struct i915_gem_context *ctx,
412394
struct intel_engine_cs *engine)
413395
{
@@ -431,12 +413,7 @@ static bool __cancel_engine(struct intel_engine_cs *engine)
431413
* kill the banned context, we fallback to doing a local reset
432414
* instead.
433415
*/
434-
if (IS_ACTIVE(CONFIG_DRM_I915_PREEMPT_TIMEOUT) &&
435-
!intel_engine_pulse(engine))
436-
return true;
437-
438-
/* If we are unable to send a pulse, try resetting this engine. */
439-
return __reset_engine(engine);
416+
return intel_engine_pulse(engine) == 0;
440417
}
441418

442419
static bool
@@ -460,8 +437,8 @@ __active_engine(struct i915_request *rq, struct intel_engine_cs **active)
460437
spin_lock(&locked->active.lock);
461438
}
462439

463-
if (!i915_request_completed(rq)) {
464-
if (i915_request_is_active(rq) && rq->fence.error != -EIO)
440+
if (i915_request_is_active(rq)) {
441+
if (!i915_request_completed(rq))
465442
*active = locked;
466443
ret = true;
467444
}
@@ -479,21 +456,34 @@ static struct intel_engine_cs *active_engine(struct intel_context *ce)
479456
if (!ce->timeline)
480457
return NULL;
481458

459+
/*
460+
* rq->link is only SLAB_TYPESAFE_BY_RCU, we need to hold a reference
461+
* to the request to prevent it being transferred to a new timeline
462+
* (and onto a new timeline->requests list).
463+
*/
482464
rcu_read_lock();
483-
list_for_each_entry_rcu(rq, &ce->timeline->requests, link) {
484-
if (i915_request_is_active(rq) && i915_request_completed(rq))
485-
continue;
465+
list_for_each_entry_reverse(rq, &ce->timeline->requests, link) {
466+
bool found;
467+
468+
/* timeline is already completed upto this point? */
469+
if (!i915_request_get_rcu(rq))
470+
break;
486471

487472
/* Check with the backend if the request is inflight */
488-
if (__active_engine(rq, &engine))
473+
found = true;
474+
if (likely(rcu_access_pointer(rq->timeline) == ce->timeline))
475+
found = __active_engine(rq, &engine);
476+
477+
i915_request_put(rq);
478+
if (found)
489479
break;
490480
}
491481
rcu_read_unlock();
492482

493483
return engine;
494484
}
495485

496-
static void kill_engines(struct i915_gem_engines *engines)
486+
static void kill_engines(struct i915_gem_engines *engines, bool ban)
497487
{
498488
struct i915_gem_engines_iter it;
499489
struct intel_context *ce;
@@ -508,7 +498,7 @@ static void kill_engines(struct i915_gem_engines *engines)
508498
for_each_gem_engine(ce, engines, it) {
509499
struct intel_engine_cs *engine;
510500

511-
if (intel_context_set_banned(ce))
501+
if (ban && intel_context_set_banned(ce))
512502
continue;
513503

514504
/*
@@ -521,7 +511,7 @@ static void kill_engines(struct i915_gem_engines *engines)
521511
engine = active_engine(ce);
522512

523513
/* First attempt to gracefully cancel the context */
524-
if (engine && !__cancel_engine(engine))
514+
if (engine && !__cancel_engine(engine) && ban)
525515
/*
526516
* If we are unable to send a preemptive pulse to bump
527517
* the context from the GPU, we have to resort to a full
@@ -531,8 +521,10 @@ static void kill_engines(struct i915_gem_engines *engines)
531521
}
532522
}
533523

534-
static void kill_stale_engines(struct i915_gem_context *ctx)
524+
static void kill_context(struct i915_gem_context *ctx)
535525
{
526+
bool ban = (!i915_gem_context_is_persistent(ctx) ||
527+
!ctx->i915->params.enable_hangcheck);
536528
struct i915_gem_engines *pos, *next;
537529

538530
spin_lock_irq(&ctx->stale.lock);
@@ -545,7 +537,7 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
545537

546538
spin_unlock_irq(&ctx->stale.lock);
547539

548-
kill_engines(pos);
540+
kill_engines(pos, ban);
549541

550542
spin_lock_irq(&ctx->stale.lock);
551543
GEM_BUG_ON(i915_sw_fence_signaled(&pos->fence));
@@ -557,11 +549,6 @@ static void kill_stale_engines(struct i915_gem_context *ctx)
557549
spin_unlock_irq(&ctx->stale.lock);
558550
}
559551

560-
static void kill_context(struct i915_gem_context *ctx)
561-
{
562-
kill_stale_engines(ctx);
563-
}
564-
565552
static void engines_idle_release(struct i915_gem_context *ctx,
566553
struct i915_gem_engines *engines)
567554
{
@@ -596,7 +583,7 @@ static void engines_idle_release(struct i915_gem_context *ctx,
596583

597584
kill:
598585
if (list_empty(&engines->link)) /* raced, already closed */
599-
kill_engines(engines);
586+
kill_engines(engines, true);
600587

601588
i915_sw_fence_commit(&engines->fence);
602589
}
@@ -654,9 +641,7 @@ static void context_close(struct i915_gem_context *ctx)
654641
* case we opt to forcibly kill off all remaining requests on
655642
* context close.
656643
*/
657-
if (!i915_gem_context_is_persistent(ctx) ||
658-
!ctx->i915->params.enable_hangcheck)
659-
kill_context(ctx);
644+
kill_context(ctx);
660645

661646
i915_gem_context_put(ctx);
662647
}

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,8 +2267,8 @@ struct eb_parse_work {
22672267
struct i915_vma *batch;
22682268
struct i915_vma *shadow;
22692269
struct i915_vma *trampoline;
2270-
unsigned int batch_offset;
2271-
unsigned int batch_length;
2270+
unsigned long batch_offset;
2271+
unsigned long batch_length;
22722272
};
22732273

22742274
static int __eb_parse(struct dma_fence_work *work)
@@ -2338,6 +2338,9 @@ static int eb_parse_pipeline(struct i915_execbuffer *eb,
23382338
struct eb_parse_work *pw;
23392339
int err;
23402340

2341+
GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset));
2342+
GEM_BUG_ON(overflows_type(eb->batch_len, pw->batch_length));
2343+
23412344
pw = kzalloc(sizeof(*pw), GFP_KERNEL);
23422345
if (!pw)
23432346
return -ENOMEM;

drivers/gpu/drm/i915/gem/i915_gem_object_blt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ int i915_gem_object_copy_blt(struct drm_i915_gem_object *src,
364364

365365
vma[1] = i915_vma_instance(dst, vm, NULL);
366366
if (IS_ERR(vma[1]))
367-
return PTR_ERR(vma);
367+
return PTR_ERR(vma[1]);
368368

369369
i915_gem_ww_ctx_init(&ww, true);
370370
intel_engine_pm_get(ce->engine);

drivers/gpu/drm/i915/gem/i915_gem_pages.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,35 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
254254
if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
255255
return NULL;
256256

257+
if (GEM_WARN_ON(type == I915_MAP_WC &&
258+
!static_cpu_has(X86_FEATURE_PAT)))
259+
return NULL;
260+
257261
/* A single page can always be kmapped */
258-
if (n_pte == 1 && type == I915_MAP_WB)
259-
return kmap(sg_page(sgt->sgl));
262+
if (n_pte == 1 && type == I915_MAP_WB) {
263+
struct page *page = sg_page(sgt->sgl);
264+
265+
/*
266+
* On 32b, highmem using a finite set of indirect PTE (i.e.
267+
* vmap) to provide virtual mappings of the high pages.
268+
* As these are finite, map_new_virtual() must wait for some
269+
* other kmap() to finish when it runs out. If we map a large
270+
* number of objects, there is no method for it to tell us
271+
* to release the mappings, and we deadlock.
272+
*
273+
* However, if we make an explicit vmap of the page, that
274+
* uses a larger vmalloc arena, and also has the ability
275+
* to tell us to release unwanted mappings. Most importantly,
276+
* it will fail and propagate an error instead of waiting
277+
* forever.
278+
*
279+
* So if the page is beyond the 32b boundary, make an explicit
280+
* vmap. On 64b, this check will be optimised away as we can
281+
* directly kmap any page on the system.
282+
*/
283+
if (!PageHighMem(page))
284+
return kmap(page);
285+
}
260286

261287
mem = stack;
262288
if (n_pte > ARRAY_SIZE(stack)) {

drivers/gpu/drm/i915/gt/intel_context.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ struct i915_request *intel_context_create_request(struct intel_context *ce)
472472
err = i915_gem_ww_ctx_backoff(&ww);
473473
if (!err)
474474
goto retry;
475+
rq = ERR_PTR(err);
475476
} else {
476477
rq = ERR_PTR(err);
477478
}

drivers/gpu/drm/i915/gt/intel_engine.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,13 @@ intel_engine_has_preempt_reset(const struct intel_engine_cs *engine)
337337
return intel_engine_has_preemption(engine);
338338
}
339339

340+
static inline bool
341+
intel_engine_has_heartbeat(const struct intel_engine_cs *engine)
342+
{
343+
if (!IS_ACTIVE(CONFIG_DRM_I915_HEARTBEAT_INTERVAL))
344+
return false;
345+
346+
return READ_ONCE(engine->props.heartbeat_interval_ms);
347+
}
348+
340349
#endif /* _INTEL_RINGBUFFER_H_ */

0 commit comments

Comments
 (0)