|
4 | 4 | * Copyright © 2018 Intel Corporation
|
5 | 5 | */
|
6 | 6 |
|
| 7 | +#include <linux/prime_numbers.h> |
| 8 | + |
7 | 9 | #include "../i915_reset.h"
|
8 | 10 |
|
9 | 11 | #include "../i915_selftest.h"
|
@@ -405,6 +407,106 @@ static int live_suppress_self_preempt(void *arg)
|
405 | 407 | goto err_client_b;
|
406 | 408 | }
|
407 | 409 |
|
| 410 | +static int live_chain_preempt(void *arg) |
| 411 | +{ |
| 412 | + struct drm_i915_private *i915 = arg; |
| 413 | + struct intel_engine_cs *engine; |
| 414 | + struct preempt_client hi, lo; |
| 415 | + enum intel_engine_id id; |
| 416 | + intel_wakeref_t wakeref; |
| 417 | + int err = -ENOMEM; |
| 418 | + |
| 419 | + /* |
| 420 | + * Build a chain AB...BA between two contexts (A, B) and request |
| 421 | + * preemption of the last request. It should then complete before |
| 422 | + * the previously submitted spinner in B. |
| 423 | + */ |
| 424 | + |
| 425 | + if (!HAS_LOGICAL_RING_PREEMPTION(i915)) |
| 426 | + return 0; |
| 427 | + |
| 428 | + mutex_lock(&i915->drm.struct_mutex); |
| 429 | + wakeref = intel_runtime_pm_get(i915); |
| 430 | + |
| 431 | + if (preempt_client_init(i915, &hi)) |
| 432 | + goto err_unlock; |
| 433 | + |
| 434 | + if (preempt_client_init(i915, &lo)) |
| 435 | + goto err_client_hi; |
| 436 | + |
| 437 | + for_each_engine(engine, i915, id) { |
| 438 | + struct i915_sched_attr attr = { |
| 439 | + .priority = I915_USER_PRIORITY(I915_PRIORITY_MAX), |
| 440 | + }; |
| 441 | + int count, i; |
| 442 | + |
| 443 | + for_each_prime_number_from(count, 1, 32) { /* must fit ring! */ |
| 444 | + struct i915_request *rq; |
| 445 | + |
| 446 | + rq = igt_spinner_create_request(&hi.spin, |
| 447 | + hi.ctx, engine, |
| 448 | + MI_ARB_CHECK); |
| 449 | + if (IS_ERR(rq)) |
| 450 | + goto err_wedged; |
| 451 | + i915_request_add(rq); |
| 452 | + if (!igt_wait_for_spinner(&hi.spin, rq)) |
| 453 | + goto err_wedged; |
| 454 | + |
| 455 | + rq = igt_spinner_create_request(&lo.spin, |
| 456 | + lo.ctx, engine, |
| 457 | + MI_ARB_CHECK); |
| 458 | + if (IS_ERR(rq)) |
| 459 | + goto err_wedged; |
| 460 | + i915_request_add(rq); |
| 461 | + |
| 462 | + for (i = 0; i < count; i++) { |
| 463 | + rq = i915_request_alloc(engine, lo.ctx); |
| 464 | + if (IS_ERR(rq)) |
| 465 | + goto err_wedged; |
| 466 | + i915_request_add(rq); |
| 467 | + } |
| 468 | + |
| 469 | + rq = i915_request_alloc(engine, hi.ctx); |
| 470 | + if (IS_ERR(rq)) |
| 471 | + goto err_wedged; |
| 472 | + i915_request_add(rq); |
| 473 | + engine->schedule(rq, &attr); |
| 474 | + |
| 475 | + igt_spinner_end(&hi.spin); |
| 476 | + if (i915_request_wait(rq, I915_WAIT_LOCKED, HZ / 5) < 0) { |
| 477 | + struct drm_printer p = |
| 478 | + drm_info_printer(i915->drm.dev); |
| 479 | + |
| 480 | + pr_err("Failed to preempt over chain of %d\n", |
| 481 | + count); |
| 482 | + intel_engine_dump(engine, &p, |
| 483 | + "%s\n", engine->name); |
| 484 | + goto err_wedged; |
| 485 | + } |
| 486 | + igt_spinner_end(&lo.spin); |
| 487 | + } |
| 488 | + } |
| 489 | + |
| 490 | + err = 0; |
| 491 | +err_client_lo: |
| 492 | + preempt_client_fini(&lo); |
| 493 | +err_client_hi: |
| 494 | + preempt_client_fini(&hi); |
| 495 | +err_unlock: |
| 496 | + if (igt_flush_test(i915, I915_WAIT_LOCKED)) |
| 497 | + err = -EIO; |
| 498 | + intel_runtime_pm_put(i915, wakeref); |
| 499 | + mutex_unlock(&i915->drm.struct_mutex); |
| 500 | + return err; |
| 501 | + |
| 502 | +err_wedged: |
| 503 | + igt_spinner_end(&hi.spin); |
| 504 | + igt_spinner_end(&lo.spin); |
| 505 | + i915_gem_set_wedged(i915); |
| 506 | + err = -EIO; |
| 507 | + goto err_client_lo; |
| 508 | +} |
| 509 | + |
408 | 510 | static int live_preempt_hang(void *arg)
|
409 | 511 | {
|
410 | 512 | struct drm_i915_private *i915 = arg;
|
@@ -785,6 +887,7 @@ int intel_execlists_live_selftests(struct drm_i915_private *i915)
|
785 | 887 | SUBTEST(live_preempt),
|
786 | 888 | SUBTEST(live_late_preempt),
|
787 | 889 | SUBTEST(live_suppress_self_preempt),
|
| 890 | + SUBTEST(live_chain_preempt), |
788 | 891 | SUBTEST(live_preempt_hang),
|
789 | 892 | SUBTEST(live_preempt_smoke),
|
790 | 893 | };
|
|
0 commit comments