Skip to content

Commit 733827e

Browse files
rtauro1895anshuma1
authored andcommitted
drm/i915/guc/slpc: Add selftest for slpc tile-tile interaction
Run a workload on tiles simultaneously by requesting for RP0 frequency. Pcode can however limit the frequency being granted due to throttling reasons. This test checks if there is any throttling but does not fail if RP0 is not granted due to throttle reasons v2: Fix build error v3: Use IS_ERR_OR_NULL to check worker Addressed cosmetic review comments (Tvrtko) v4: do not skip test on media engines if gt type is GT_MEDIA. Use correct PERF_LIMIT_REASONS register for MTL (Vinay) Signed-off-by: Riana Tauro <[email protected]> Reviewed-by: Vinay Belgaumkar <[email protected]> Signed-off-by: Anshuman Gupta <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 9bae30d commit 733827e

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

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

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ enum test_type {
1313
VARY_MAX,
1414
MAX_GRANTED,
1515
SLPC_POWER,
16+
TILE_INTERACTION,
17+
};
18+
19+
struct slpc_thread {
20+
struct kthread_worker *worker;
21+
struct kthread_work work;
22+
struct intel_gt *gt;
23+
int result;
1624
};
1725

1826
static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq)
@@ -212,7 +220,8 @@ static int max_granted_freq(struct intel_guc_slpc *slpc, struct intel_rps *rps,
212220
*max_act_freq = intel_rps_read_actual_frequency(rps);
213221
if (*max_act_freq != slpc->rp0_freq) {
214222
/* Check if there was some throttling by pcode */
215-
perf_limit_reasons = intel_uncore_read(gt->uncore, GT0_PERF_LIMIT_REASONS);
223+
perf_limit_reasons = intel_uncore_read(gt->uncore,
224+
intel_gt_perf_limit_reasons_reg(gt));
216225

217226
/* If not, this is an error */
218227
if (!(perf_limit_reasons & GT0_PERF_LIMIT_REASONS_MASK)) {
@@ -310,9 +319,10 @@ static int run_test(struct intel_gt *gt, int test_type)
310319
break;
311320

312321
case MAX_GRANTED:
322+
case TILE_INTERACTION:
313323
/* Media engines have a different RP0 */
314-
if (engine->class == VIDEO_DECODE_CLASS ||
315-
engine->class == VIDEO_ENHANCEMENT_CLASS) {
324+
if (gt->type != GT_MEDIA && (engine->class == VIDEO_DECODE_CLASS ||
325+
engine->class == VIDEO_ENHANCEMENT_CLASS)) {
316326
igt_spinner_end(&spin);
317327
st_engine_heartbeat_enable(engine);
318328
err = 0;
@@ -335,7 +345,8 @@ static int run_test(struct intel_gt *gt, int test_type)
335345
if (max_act_freq <= slpc->min_freq) {
336346
pr_err("Actual freq did not rise above min\n");
337347
pr_err("Perf Limit Reasons: 0x%x\n",
338-
intel_uncore_read(gt->uncore, GT0_PERF_LIMIT_REASONS));
348+
intel_uncore_read(gt->uncore,
349+
intel_gt_perf_limit_reasons_reg(gt)));
339350
err = -EINVAL;
340351
}
341352
}
@@ -426,13 +437,64 @@ static int live_slpc_power(void *arg)
426437
return ret;
427438
}
428439

440+
static void slpc_spinner_thread(struct kthread_work *work)
441+
{
442+
struct slpc_thread *thread = container_of(work, typeof(*thread), work);
443+
444+
thread->result = run_test(thread->gt, TILE_INTERACTION);
445+
}
446+
447+
static int live_slpc_tile_interaction(void *arg)
448+
{
449+
struct drm_i915_private *i915 = arg;
450+
struct intel_gt *gt;
451+
struct slpc_thread *threads;
452+
int i = 0, ret = 0;
453+
454+
threads = kcalloc(I915_MAX_GT, sizeof(*threads), GFP_KERNEL);
455+
if (!threads)
456+
return -ENOMEM;
457+
458+
for_each_gt(gt, i915, i) {
459+
threads[i].worker = kthread_create_worker(0, "igt/slpc_parallel:%d", gt->info.id);
460+
461+
if (IS_ERR(threads[i].worker)) {
462+
ret = PTR_ERR(threads[i].worker);
463+
break;
464+
}
465+
466+
threads[i].gt = gt;
467+
kthread_init_work(&threads[i].work, slpc_spinner_thread);
468+
kthread_queue_work(threads[i].worker, &threads[i].work);
469+
}
470+
471+
for_each_gt(gt, i915, i) {
472+
int status;
473+
474+
if (IS_ERR_OR_NULL(threads[i].worker))
475+
continue;
476+
477+
kthread_flush_work(&threads[i].work);
478+
status = READ_ONCE(threads[i].result);
479+
if (status && !ret) {
480+
pr_err("%s GT %d failed ", __func__, gt->info.id);
481+
ret = status;
482+
}
483+
kthread_destroy_worker(threads[i].worker);
484+
}
485+
486+
kfree(threads);
487+
return ret;
488+
}
489+
429490
int intel_slpc_live_selftests(struct drm_i915_private *i915)
430491
{
431492
static const struct i915_subtest tests[] = {
432493
SUBTEST(live_slpc_vary_max),
433494
SUBTEST(live_slpc_vary_min),
434495
SUBTEST(live_slpc_max_granted),
435496
SUBTEST(live_slpc_power),
497+
SUBTEST(live_slpc_tile_interaction),
436498
};
437499

438500
struct intel_gt *gt;

0 commit comments

Comments
 (0)