Message ID | 20221028095058.3624647-2-riana.tauro@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add selftest for slpc tile interaction | expand |
Hi, I peeked inside from curiosity and was pleasantly surprise to see kthread_work is used! Some comments below. On 28/10/2022 10:50, Riana Tauro wrote: > 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 fails if there is any throttling > > v2: Fix build error > > Signed-off-by: Riana Tauro <riana.tauro@intel.com> > --- > drivers/gpu/drm/i915/gt/selftest_slpc.c | 63 +++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > > diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c b/drivers/gpu/drm/i915/gt/selftest_slpc.c > index 82ec95a299f6..d19486772f5a 100644 > --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c > +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c > @@ -13,6 +13,14 @@ enum test_type { > VARY_MAX, > MAX_GRANTED, > SLPC_POWER, > + TILE_INTERACTION, > +}; > + > +struct slpc_thread { > + struct kthread_worker *worker; > + struct kthread_work work; > + struct intel_gt *gt; > + int result; > }; > > static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq) > @@ -310,6 +318,7 @@ static int run_test(struct intel_gt *gt, int test_type) > break; > > case MAX_GRANTED: > + case TILE_INTERACTION: > /* Media engines have a different RP0 */ > if (engine->class == VIDEO_DECODE_CLASS || > engine->class == VIDEO_ENHANCEMENT_CLASS) { > @@ -325,6 +334,7 @@ static int run_test(struct intel_gt *gt, int test_type) > case SLPC_POWER: > err = slpc_power(gt, engine); > break; > + Noise. > } > > if (test_type != SLPC_POWER) { > @@ -426,6 +436,58 @@ static int live_slpc_power(void *arg) > return ret; > } > > +static void slpc_spinner_thread(struct kthread_work *work) > +{ > + struct slpc_thread *thread = container_of(work, typeof(*thread), work); > + > + thread->result = run_test(thread->gt, TILE_INTERACTION); > +} > + > +static int live_slpc_tile_interaction(void *arg) > +{ > + struct drm_i915_private *i915 = arg; > + struct intel_gt *gt; > + struct slpc_thread *threads; > + int i = 0, ret = 0; > + > + threads = kcalloc(I915_MAX_GT, sizeof(*threads), GFP_KERNEL); > + if (!threads) > + return -ENOMEM; > + > + for_each_gt(gt, i915, i) { > + pr_info("Running on GT: %d\n", gt->info.id); Not sure logging these makes sense since test runs on all tiles in parallel anyway. > + threads[i].worker = kthread_create_worker(0, "igt/slpc_parallel:%d", gt->info.id); > + > + if (IS_ERR(threads[i].worker)) { > + ret = PTR_ERR(threads[i].worker); > + break; > + } > + > + threads[i].gt = gt; > + threads[i].result = 0; No need to zero result due kcalloc and runs do not repeat. > + kthread_init_work(&threads[i].work, slpc_spinner_thread); > + kthread_queue_work(threads[i].worker, &threads[i].work); > + } > + > + for_each_gt(gt, i915, i) { > + int status; > + > + if (!threads[i].worker) > + continue; Could be ERR_PTR by the look of it so it would crash below. Either gate on threads[i].gt or use IS_ERR_OR_NULL. Regards, Tvrtko > + > + kthread_flush_work(&threads[i].work); > + status = READ_ONCE(threads[i].result); > + if (status && !ret) { > + pr_err("%s GT %d failed ", __func__, gt->info.id); > + ret = status; > + } > + kthread_destroy_worker(threads[i].worker); > + } > + > + kfree(threads); > + return ret; > +} > + > int intel_slpc_live_selftests(struct drm_i915_private *i915) > { > static const struct i915_subtest tests[] = { > @@ -433,6 +495,7 @@ int intel_slpc_live_selftests(struct drm_i915_private *i915) > SUBTEST(live_slpc_vary_min), > SUBTEST(live_slpc_max_granted), > SUBTEST(live_slpc_power), > + SUBTEST(live_slpc_tile_interaction), > }; > > struct intel_gt *gt;
On 10/28/2022 3:53 PM, Tvrtko Ursulin wrote: > > Hi, > > I peeked inside from curiosity and was pleasantly surprise to see > kthread_work is used! Some comments below. > > On 28/10/2022 10:50, Riana Tauro wrote: >> 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 fails if there is any throttling >> >> v2: Fix build error >> >> Signed-off-by: Riana Tauro <riana.tauro@intel.com> >> --- >> drivers/gpu/drm/i915/gt/selftest_slpc.c | 63 +++++++++++++++++++++++++ >> 1 file changed, 63 insertions(+) >> >> diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c >> b/drivers/gpu/drm/i915/gt/selftest_slpc.c >> index 82ec95a299f6..d19486772f5a 100644 >> --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c >> +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c >> @@ -13,6 +13,14 @@ enum test_type { >> VARY_MAX, >> MAX_GRANTED, >> SLPC_POWER, >> + TILE_INTERACTION, >> +}; >> + >> +struct slpc_thread { >> + struct kthread_worker *worker; >> + struct kthread_work work; >> + struct intel_gt *gt; >> + int result; >> }; >> static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq) >> @@ -310,6 +318,7 @@ static int run_test(struct intel_gt *gt, int >> test_type) >> break; >> case MAX_GRANTED: >> + case TILE_INTERACTION: >> /* Media engines have a different RP0 */ >> if (engine->class == VIDEO_DECODE_CLASS || >> engine->class == VIDEO_ENHANCEMENT_CLASS) { >> @@ -325,6 +334,7 @@ static int run_test(struct intel_gt *gt, int >> test_type) >> case SLPC_POWER: >> err = slpc_power(gt, engine); >> break; >> + > > Noise. > >> } >> if (test_type != SLPC_POWER) { >> @@ -426,6 +436,58 @@ static int live_slpc_power(void *arg) >> return ret; >> } >> +static void slpc_spinner_thread(struct kthread_work *work) >> +{ >> + struct slpc_thread *thread = container_of(work, typeof(*thread), >> work); >> + >> + thread->result = run_test(thread->gt, TILE_INTERACTION); >> +} >> + >> +static int live_slpc_tile_interaction(void *arg) >> +{ >> + struct drm_i915_private *i915 = arg; >> + struct intel_gt *gt; >> + struct slpc_thread *threads; >> + int i = 0, ret = 0; >> + >> + threads = kcalloc(I915_MAX_GT, sizeof(*threads), GFP_KERNEL); >> + if (!threads) >> + return -ENOMEM; >> + >> + for_each_gt(gt, i915, i) { >> + pr_info("Running on GT: %d\n", gt->info.id); > > Not sure logging these makes sense since test runs on all tiles in > parallel anyway. > >> + threads[i].worker = kthread_create_worker(0, >> "igt/slpc_parallel:%d", gt->info.id); >> + >> + if (IS_ERR(threads[i].worker)) { >> + ret = PTR_ERR(threads[i].worker); >> + break; >> + } >> + >> + threads[i].gt = gt; >> + threads[i].result = 0; > > No need to zero result due kcalloc and runs do not repeat. > >> + kthread_init_work(&threads[i].work, slpc_spinner_thread); >> + kthread_queue_work(threads[i].worker, &threads[i].work); >> + } >> + >> + for_each_gt(gt, i915, i) { >> + int status; >> + >> + if (!threads[i].worker) >> + continue; > > Could be ERR_PTR by the look of it so it would crash below. Either gate > on threads[i].gt or use IS_ERR_OR_NULL. > > Regards, > > Tvrtko Thank you Tvrtko for the review comments. Will fix these. Thanks Riana > >> + >> + kthread_flush_work(&threads[i].work); >> + status = READ_ONCE(threads[i].result); >> + if (status && !ret) { >> + pr_err("%s GT %d failed ", __func__, gt->info.id); >> + ret = status; >> + } >> + kthread_destroy_worker(threads[i].worker); >> + } >> + >> + kfree(threads); >> + return ret; >> +} >> + >> int intel_slpc_live_selftests(struct drm_i915_private *i915) >> { >> static const struct i915_subtest tests[] = { >> @@ -433,6 +495,7 @@ int intel_slpc_live_selftests(struct >> drm_i915_private *i915) >> SUBTEST(live_slpc_vary_min), >> SUBTEST(live_slpc_max_granted), >> SUBTEST(live_slpc_power), >> + SUBTEST(live_slpc_tile_interaction), >> }; >> struct intel_gt *gt;
diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c b/drivers/gpu/drm/i915/gt/selftest_slpc.c index 82ec95a299f6..d19486772f5a 100644 --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c @@ -13,6 +13,14 @@ enum test_type { VARY_MAX, MAX_GRANTED, SLPC_POWER, + TILE_INTERACTION, +}; + +struct slpc_thread { + struct kthread_worker *worker; + struct kthread_work work; + struct intel_gt *gt; + int result; }; static int slpc_set_min_freq(struct intel_guc_slpc *slpc, u32 freq) @@ -310,6 +318,7 @@ static int run_test(struct intel_gt *gt, int test_type) break; case MAX_GRANTED: + case TILE_INTERACTION: /* Media engines have a different RP0 */ if (engine->class == VIDEO_DECODE_CLASS || engine->class == VIDEO_ENHANCEMENT_CLASS) { @@ -325,6 +334,7 @@ static int run_test(struct intel_gt *gt, int test_type) case SLPC_POWER: err = slpc_power(gt, engine); break; + } if (test_type != SLPC_POWER) { @@ -426,6 +436,58 @@ static int live_slpc_power(void *arg) return ret; } +static void slpc_spinner_thread(struct kthread_work *work) +{ + struct slpc_thread *thread = container_of(work, typeof(*thread), work); + + thread->result = run_test(thread->gt, TILE_INTERACTION); +} + +static int live_slpc_tile_interaction(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_gt *gt; + struct slpc_thread *threads; + int i = 0, ret = 0; + + threads = kcalloc(I915_MAX_GT, sizeof(*threads), GFP_KERNEL); + if (!threads) + return -ENOMEM; + + for_each_gt(gt, i915, i) { + pr_info("Running on GT: %d\n", gt->info.id); + threads[i].worker = kthread_create_worker(0, "igt/slpc_parallel:%d", gt->info.id); + + if (IS_ERR(threads[i].worker)) { + ret = PTR_ERR(threads[i].worker); + break; + } + + threads[i].gt = gt; + threads[i].result = 0; + kthread_init_work(&threads[i].work, slpc_spinner_thread); + kthread_queue_work(threads[i].worker, &threads[i].work); + } + + for_each_gt(gt, i915, i) { + int status; + + if (!threads[i].worker) + continue; + + kthread_flush_work(&threads[i].work); + status = READ_ONCE(threads[i].result); + if (status && !ret) { + pr_err("%s GT %d failed ", __func__, gt->info.id); + ret = status; + } + kthread_destroy_worker(threads[i].worker); + } + + kfree(threads); + return ret; +} + int intel_slpc_live_selftests(struct drm_i915_private *i915) { static const struct i915_subtest tests[] = { @@ -433,6 +495,7 @@ int intel_slpc_live_selftests(struct drm_i915_private *i915) SUBTEST(live_slpc_vary_min), SUBTEST(live_slpc_max_granted), SUBTEST(live_slpc_power), + SUBTEST(live_slpc_tile_interaction), }; struct intel_gt *gt;
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 fails if there is any throttling v2: Fix build error Signed-off-by: Riana Tauro <riana.tauro@intel.com> --- drivers/gpu/drm/i915/gt/selftest_slpc.c | 63 +++++++++++++++++++++++++ 1 file changed, 63 insertions(+)