+ 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