[igt-dev] [Intel-gfx] [PATCH v2 i-g-t] tests/i915_pm_freq_api: Add a suspend subtest

Dixit, Ashutosh ashutosh.dixit at intel.com
Tue Jun 13 21:25:48 UTC 2023


On Mon, 12 Jun 2023 12:42:13 -0700, Vinay Belgaumkar wrote:
>

Hi Vinay,

> Verify that SLPC API works as expected after a suspend. Added
> another subtest that does multiple GT resets and checks freq api
> works as expected after each one.
>
> We now check requested frequency instead of soft min/max after a
> reset or suspend. That ensures the soft limits got applied
> correctly at init. Also, disable efficient freq before starting the
> test which allows current freq to be consistent with SLPC min freq.
>
> v2: Restore freq in exit handler (Ashutosh)
>
> Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar at intel.com>
> ---
>  tests/i915/i915_pm_freq_api.c | 89 +++++++++++++++++++++++++++--------
>  1 file changed, 69 insertions(+), 20 deletions(-)
>
> diff --git a/tests/i915/i915_pm_freq_api.c b/tests/i915/i915_pm_freq_api.c
> index 9005cd220..4e1d4edca 100644
> --- a/tests/i915/i915_pm_freq_api.c
> +++ b/tests/i915/i915_pm_freq_api.c
> @@ -18,6 +18,12 @@
>   *
>   * SUBTEST: freq-reset
>   * Description: Test basic freq API works after a reset
> + *
> + * SUBTEST: freq-reset-multiple
> + * Description: Test basic freq API works after multiple resets
> + *
> + * SUBTEST: freq-suspend
> + * Description: Test basic freq API works after a runtime suspend
>   */
>
>  IGT_TEST_DESCRIPTION("Test SLPC freq API");
> @@ -79,31 +85,64 @@ static void test_freq_basic_api(int dirfd, int gt)
>
>  }
>
> -static void test_reset(int i915, int dirfd, int gt)
> +static void test_reset(int i915, int dirfd, int gt, int count)
>  {
>	uint32_t rpn = get_freq(dirfd, RPS_RPn_FREQ_MHZ);
>	int fd;
>
> +	for (int i = 0; i < count; i++) {
> +		igt_assert_f(set_freq(dirfd, RPS_MIN_FREQ_MHZ, rpn) > 0,
> +			     "Failed after %d good cycles\n", i);
> +		igt_assert_f(set_freq(dirfd, RPS_MAX_FREQ_MHZ, rpn) > 0,
> +			     "Failed after %d good cycles\n", i);
> +		usleep(ACT_FREQ_LATENCY_US);
> +		igt_assert_f(get_freq(dirfd, RPS_CUR_FREQ_MHZ) == rpn,
> +			     "Failed after %d good cycles\n", i);
> +
> +		/* Manually trigger a GT reset */
> +		fd = igt_debugfs_gt_open(i915, gt, "reset", O_WRONLY);
> +		igt_require(fd >= 0);
> +		igt_ignore_warn(write(fd, "1\n", 2));

No need for 'usleep(ACT_FREQ_LATENCY_US)' here?

> +
> +		igt_assert_f(get_freq(dirfd, RPS_CUR_FREQ_MHZ) == rpn,
> +			     "Failed after %d good cycles\n", i);
> +	}
> +	close(fd);
> +}
> +
> +static void test_suspend(int i915, int dirfd, int gt)
> +{
> +	uint32_t rpn = get_freq(dirfd, RPS_RPn_FREQ_MHZ);
> +
>	igt_assert(set_freq(dirfd, RPS_MIN_FREQ_MHZ, rpn) > 0);
>	igt_assert(set_freq(dirfd, RPS_MAX_FREQ_MHZ, rpn) > 0);
>	usleep(ACT_FREQ_LATENCY_US);
> -	igt_assert(get_freq(dirfd, RPS_MIN_FREQ_MHZ) == rpn);
> +	igt_assert(get_freq(dirfd, RPS_CUR_FREQ_MHZ) == rpn);
>
> -	/* Manually trigger a GT reset */
> -	fd = igt_debugfs_gt_open(i915, gt, "reset", O_WRONLY);
> -	igt_require(fd >= 0);
> -	igt_ignore_warn(write(fd, "1\n", 2));
> -	close(fd);
> +	/* Manually trigger a suspend */
> +	igt_system_suspend_autoresume(SUSPEND_STATE_S3,
> +				      SUSPEND_TEST_NONE);

No need for 'usleep(ACT_FREQ_LATENCY_US)' here?

>
> -	igt_assert(get_freq(dirfd, RPS_MIN_FREQ_MHZ) == rpn);
> -	igt_assert(get_freq(dirfd, RPS_MAX_FREQ_MHZ) == rpn);
> +	igt_assert(get_freq(dirfd, RPS_CUR_FREQ_MHZ) == rpn);
>  }
>
> -igt_main
> +int i915 = -1;
> +uint32_t *stash_min, *stash_max;

nit: could we maybe make these fixed size array's (2 or 4 entries) and drop
the malloc's for these, malloc's seem excessive in this case.

> +
> +static void restore_sysfs_freq(int sig)
>  {
> -	int i915 = -1;
> -	uint32_t *stash_min, *stash_max;
> +	int dirfd, gt;
> +	/* Restore frequencies */
> +	for_each_sysfs_gt_dirfd(i915, dirfd, gt) {
> +		igt_pm_ignore_slpc_efficient_freq(i915, dirfd, false);
> +		igt_assert(set_freq(dirfd, RPS_MAX_FREQ_MHZ, stash_max[gt]) > 0);
> +		igt_assert(set_freq(dirfd, RPS_MIN_FREQ_MHZ, stash_min[gt]) > 0);

nit: I would remove the igt_assert's from here, it's basically a best
effort restore so we try to restore everything even if we fail.

> +	}
> +	close(i915);
> +}
>
> +igt_main
> +{
>	igt_fixture {
>		int num_gts, dirfd, gt;
>
> @@ -122,7 +161,9 @@ igt_main
>		for_each_sysfs_gt_dirfd(i915, dirfd, gt) {
>			stash_min[gt] = get_freq(dirfd, RPS_MIN_FREQ_MHZ);
>			stash_max[gt] = get_freq(dirfd, RPS_MAX_FREQ_MHZ);
> +			igt_pm_ignore_slpc_efficient_freq(i915, dirfd, true);
>		}
> +		igt_install_exit_handler(restore_sysfs_freq);
>	}
>
>	igt_describe("Test basic API for controlling min/max GT frequency");
> @@ -140,16 +181,24 @@ igt_main
>
>		for_each_sysfs_gt_dirfd(i915, dirfd, gt)
>			igt_dynamic_f("gt%u", gt)
> -				test_reset(i915, dirfd, gt);
> +				test_reset(i915, dirfd, gt, 1);
>	}
>
> -	igt_fixture {
> +	igt_describe("Test basic freq API works after multiple resets");
> +	igt_subtest_with_dynamic_f("freq-reset-multiple") {
>		int dirfd, gt;
> -		/* Restore frequencies */
> -		for_each_sysfs_gt_dirfd(i915, dirfd, gt) {
> -			igt_assert(set_freq(dirfd, RPS_MAX_FREQ_MHZ, stash_max[gt]) > 0);
> -			igt_assert(set_freq(dirfd, RPS_MIN_FREQ_MHZ, stash_min[gt]) > 0);
> -		}
> -		close(i915);
> +
> +		for_each_sysfs_gt_dirfd(i915, dirfd, gt)
> +			igt_dynamic_f("gt%u", gt)
> +				test_reset(i915, dirfd, gt, 50);
> +	}

Do we need both "freq-reset" and "freq-reset-multiple"? Since
"freq-reset" is a subset of "freq-reset-multiple"? Or we want "freq-reset"
to run as part of BAT and "freq-reset-multiple" as part of shards e.g.?

> +
> +	igt_describe("Test basic freq API works after suspend");
> +	igt_subtest_with_dynamic_f("freq-suspend") {
> +		int dirfd, gt;
> +
> +		for_each_sysfs_gt_dirfd(i915, dirfd, gt)
> +			igt_dynamic_f("gt%u", gt)
> +				test_suspend(i915, dirfd, gt);
>	}
>  }
> --
> 2.38.1
>

Thanks.
--
Ashutosh


More information about the igt-dev mailing list