[igt-dev] [PATCH i-g-t 2/2] tests/i915_pm_rps: Exercise sysfs thresholds
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Mon Jul 17 08:37:18 UTC 2023
On 14/07/2023 18:26, Rodrigo Vivi wrote:
> On Tue, Jul 11, 2023 at 05:02:14PM +0100, Tvrtko Ursulin wrote:
>> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>>
>> Exercise a bunch of up and down rps thresholds to verify hardware
>> is happy with them all.
>>
>> To limit the overall runtime relies on probability and number of runs
>> to approach complete coverage.
>>
>> v2:
>> * Common sync spinner code now in library.
>>
>> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>> Cc: Rodrigo Vivi <rodrigo.vivi at intel.com>
>> ---
>> tests/i915/i915_pm_rps.c | 194 +++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 194 insertions(+)
>>
>> diff --git a/tests/i915/i915_pm_rps.c b/tests/i915/i915_pm_rps.c
>> index 7044fcd81c56..8c370b35c85b 100644
>> --- a/tests/i915/i915_pm_rps.c
>> +++ b/tests/i915/i915_pm_rps.c
>> @@ -39,8 +39,10 @@
>> #include "i915/gem.h"
>> #include "i915/gem_create.h"
>> #include "igt.h"
>> +#include "igt_aux.h"
>> #include "igt_dummyload.h"
>> #include "igt_perf.h"
>> +#include "igt_rand.h"
>> #include "igt_sysfs.h"
>> /**
>> * TEST: i915 pm rps
>> @@ -81,6 +83,22 @@
>> * SUBTEST: waitboost
>> * Feature: pm_rps
>> * Run type: FULL
>> + *
>> + * SUBTEST: thresholds
>> + * Feature: pm_rps
>> + * Run type: FULL
>> + *
>> + * SUBTEST: thresholds-idle
>> + * Feature: pm_rps
>> + * Run type: FULL
>> + *
>> + * SUBTEST: thresholds-idle-park
>> + * Feature: pm_rps
>> + * Run type: FULL
>> + *
>> + * SUBTEST: thresholds-park
>> + * Feature: pm_rps
>> + * Run type: FULL
>> */
>>
>> IGT_TEST_DESCRIPTION("Render P-States tests - verify GPU frequency changes");
>> @@ -920,6 +938,146 @@ static void pm_rps_exit_handler(int sig)
>> drm_close_driver(drm_fd);
>> }
>>
>> +static struct i915_engine_class_instance
>> +find_dword_engine(int i915, const unsigned int gt)
>> +{
>> + struct i915_engine_class_instance *engines, ci = { -1, -1 };
>> + unsigned int i, count;
>> +
>> + engines = gem_list_engines(i915, 1u << gt, ~0u, &count);
>> + igt_assert(engines);
>> +
>> + for (i = 0; i < count; i++) {
>> + if (!gem_class_can_store_dword(i915, engines[i].engine_class))
>> + continue;
>> +
>> + ci = engines[i];
>> + break;
>> + }
>> +
>> + free(engines);
>> +
>> + return ci;
>> +}
>> +
>> +static igt_spin_t *spin_sync_gt(int i915, uint64_t ahnd, unsigned int gt,
>> + const intel_ctx_t **ctx)
>> +{
>> + struct i915_engine_class_instance ci = { -1, -1 };
>> + struct intel_execution_engine2 e = { };
>> +
>> + ci = find_dword_engine(i915, gt);
>> +
>> + igt_require(ci.engine_class != (uint16_t)I915_ENGINE_CLASS_INVALID);
>> +
>> + if (gem_has_contexts(i915)) {
>> + e.class = ci.engine_class;
>> + e.instance = ci.engine_instance;
>> + e.flags = 0;
>> + *ctx = intel_ctx_create_for_engine(i915, e.class, e.instance);
>> + } else {
>> + igt_require(gt == 0); /* Impossible anyway. */
>
> I'm confused by the comment here... if it is impossible why we have code below?!
> but why impossible?
Only the gt != 0 part would be impossible in this !gem_has_context
branch, otherwise the branch runs on old platforms (which are always
single tile). Perhaps a case of too many asserts adding confusion?
>
> anyway, the tests below are great for the sysfs that you are adding. Thanks
>
> Reviewed-by: Rodrigo Vivi <rodrigo.vivi at intel.com>
Thanks!
Regards,
Tvrtko
>
>> + e.class = gem_execbuf_flags_to_engine_class(I915_EXEC_DEFAULT);
>> + e.instance = 0;
>> + e.flags = I915_EXEC_DEFAULT;
>> + *ctx = intel_ctx_0(i915);
>> + }
>> +
>> + igt_debug("Using engine %u:%u\n", e.class, e.instance);
>> +
>> + return __igt_sync_spin(i915, ahnd, *ctx, &e);
>> +}
>> +
>> +#define TEST_IDLE 0x1
>> +#define TEST_PARK 0x2
>> +static void test_thresholds(int i915, unsigned int gt, unsigned int flags)
>> +{
>> + uint64_t ahnd = get_reloc_ahnd(i915, 0);
>> + const unsigned int points = 10;
>> + unsigned int def_up, def_down;
>> + igt_spin_t *spin = NULL;
>> + const intel_ctx_t *ctx;
>> + unsigned int *ta, *tb;
>> + unsigned int i;
>> + int sysfs;
>> +
>> + sysfs = igt_sysfs_gt_open(i915, gt);
>> + igt_require(sysfs >= 0);
>> +
>> + /* Feature test */
>> + def_up = igt_sysfs_get_u32(sysfs, "rps_up_threshold_pct");
>> + def_down = igt_sysfs_get_u32(sysfs, "rps_down_threshold_pct");
>> + igt_require(def_up && def_down);
>> +
>> + /* Check invalid percentages are rejected */
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_up_threshold_pct", 101), false);
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_down_threshold_pct", 101), false);
>> +
>> + /*
>> + * Invent some random up-down thresholds, but always include 0 and 100
>> + * just to have some wild edge cases.
>> + */
>> + ta = calloc(points, sizeof(unsigned int));
>> + tb = calloc(points, sizeof(unsigned int));
>> + igt_require(ta && tb);
>> +
>> + ta[0] = tb[0] = 0;
>> + ta[1] = tb[1] = 100;
>> + hars_petruska_f54_1_random_seed(time(NULL));
>> + for (i = 2; i < points; i++) {
>> + ta[i] = hars_petruska_f54_1_random_unsafe_max(100);
>> + tb[i] = hars_petruska_f54_1_random_unsafe_max(100);
>> + }
>> + igt_permute_array(ta, points, igt_exchange_int);
>> + igt_permute_array(tb, points, igt_exchange_int);
>> +
>> + /* Exercise the thresholds with a GPU load to trigger park/unpark etc */
>> + for (i = 0; i < points; i++) {
>> + igt_info("Testing thresholds up %u%% and down %u%%...\n", ta[i], tb[i]);
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_up_threshold_pct", ta[i]), true);
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_down_threshold_pct", tb[i]), true);
>> +
>> + if (flags & TEST_IDLE) {
>> + gem_quiescent_gpu(i915);
>> + } else if (spin) {
>> + intel_ctx_destroy(i915, ctx);
>> + igt_spin_free(i915, spin);
>> + spin = NULL;
>> + if (flags & TEST_PARK) {
>> + gem_quiescent_gpu(i915);
>> + usleep(500000);
>> + }
>> + }
>> + spin = spin_sync_gt(i915, ahnd, gt, &ctx);
>> + usleep(1000000);
>> + if (flags & TEST_IDLE) {
>> + intel_ctx_destroy(i915, ctx);
>> + igt_spin_free(i915, spin);
>> + if (flags & TEST_PARK) {
>> + gem_quiescent_gpu(i915);
>> + usleep(500000);
>> + }
>> + spin = NULL;
>> + }
>> + }
>> +
>> + if (spin) {
>> + intel_ctx_destroy(i915, ctx);
>> + igt_spin_free(i915, spin);
>> + }
>> +
>> + gem_quiescent_gpu(i915);
>> +
>> + /* Restore defaults */
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_up_threshold_pct", def_up), true);
>> + igt_assert_eq(igt_sysfs_set_u32(sysfs, "rps_down_threshold_pct", def_down), true);
>> +
>> + free(ta);
>> + free(tb);
>> + close(sysfs);
>> + put_ahnd(ahnd);
>> +}
>> +
>> igt_main
>> {
>> igt_fixture {
>> @@ -1000,6 +1158,42 @@ igt_main
>> igt_disallow_hang(drm_fd, hang);
>> }
>>
>> + igt_subtest_with_dynamic("thresholds-idle") {
>> + int tmp, gt;
>> +
>> + i915_for_each_gt(drm_fd, tmp, gt) {
>> + igt_dynamic_f("gt%u", gt)
>> + test_thresholds(drm_fd, gt, TEST_IDLE);
>> + }
>> + }
>> +
>> + igt_subtest_with_dynamic("thresholds") {
>> + int tmp, gt;
>> +
>> + i915_for_each_gt(drm_fd, tmp, gt) {
>> + igt_dynamic_f("gt%u", gt)
>> + test_thresholds(drm_fd, gt, 0);
>> + }
>> + }
>> +
>> + igt_subtest_with_dynamic("thresholds-park") {
>> + int tmp, gt;
>> +
>> + i915_for_each_gt(drm_fd, tmp, gt) {
>> + igt_dynamic_f("gt%u", gt)
>> + test_thresholds(drm_fd, gt, TEST_PARK);
>> + }
>> + }
>> +
>> + igt_subtest_with_dynamic("thresholds-idle-park") {
>> + int tmp, gt;
>> +
>> + i915_for_each_gt(drm_fd, tmp, gt) {
>> + igt_dynamic_f("gt%u", gt)
>> + test_thresholds(drm_fd, gt, TEST_IDLE | TEST_PARK);
>> + }
>> + }
>> +
>> igt_fixture
>> drm_close_driver(drm_fd);
>> }
>> --
>> 2.39.2
>>
More information about the igt-dev
mailing list