[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