[igt-dev] [PATCH] tests/intel: Add multi gt support for rc6_residency test
Sujaritha Sundaresan
sujaritha.sundaresan at intel.com
Wed Nov 8 06:43:12 UTC 2023
Adding multi-gt support for rc6_idle, rc6_fence and rc6_accuracy tests.
Signed-off-by: Sujaritha Sundaresan <sujaritha.sundaresan at intel.com>
---
tests/intel/i915_pm_rc6_residency.c | 134 ++++++++++++++++++----------
1 file changed, 85 insertions(+), 49 deletions(-)
diff --git a/tests/intel/i915_pm_rc6_residency.c b/tests/intel/i915_pm_rc6_residency.c
index b266680ac..f865fbe94 100644
--- a/tests/intel/i915_pm_rc6_residency.c
+++ b/tests/intel/i915_pm_rc6_residency.c
@@ -36,6 +36,7 @@
#include "i915/gem.h"
#include "i915/gem_create.h"
#include "igt.h"
+#include "igt_debugfs.h"
#include "igt_perf.h"
#include "igt_power.h"
#include "igt_sysfs.h"
@@ -82,23 +83,19 @@ static unsigned long get_rc6_enabled_mask(void)
return enabled;
}
-static bool has_rc6_residency(const char *name)
+static bool has_rc6_residency(int dirfd, enum i915_attr_id id)
{
unsigned long residency;
- char path[128];
- sprintf(path, "power/%s_residency_ms", name);
- return igt_sysfs_scanf(sysfs, path, "%lu", &residency) == 1;
+ return igt_sysfs_rps_scanf(dirfd, id, "%lu", &residency) == 1;
}
-static unsigned long read_rc6_residency(const char *name)
+static unsigned long read_rc6_residency(int dirfd, enum i915_attr_id id)
{
unsigned long residency;
- char path[128];
residency = 0;
- sprintf(path, "power/%s_residency_ms", name);
- igt_assert(igt_sysfs_scanf(sysfs, path, "%lu", &residency) == 1);
+ igt_assert(igt_sysfs_rps_scanf(dirfd, id, "%lu", &residency) == 1);
return residency;
}
@@ -107,11 +104,14 @@ static void residency_accuracy(unsigned int diff,
const char *name_of_rc6_residency)
{
double ratio;
+ int gt = 0, gt_current;
ratio = (double)diff / duration;
- igt_info("Residency in %s or deeper state: %u ms (sleep duration %u ms) (%.1f%% of expected duration)\n",
- name_of_rc6_residency, diff, duration, 100*ratio);
+ gt_current = igt_sysfs_get_u32(gt, "id");
+
+ igt_info("GT[%d]: Residency in %s or deeper state: %u ms (sleep duration %u ms) (%.1f%% of expected duration)\n",
+ gt_current, name_of_rc6_residency, diff, duration, 100*ratio);
igt_assert_f(ratio > 0.9 && ratio < 1.05,
"Sysfs RC6 residency counter is inaccurate.\n");
}
@@ -125,28 +125,28 @@ static unsigned long gettime_ms(void)
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
-static void read_residencies(int devid, unsigned int mask,
+static void read_residencies(int devid, int dirfd, unsigned int mask,
struct residencies *res)
{
res->duration = gettime_ms();
if (mask & RC6_ENABLED)
- res->rc6 = read_rc6_residency("rc6");
+ res->rc6 = read_rc6_residency(dirfd, RC6_RESIDENCY_MS);
if ((mask & RC6_ENABLED) &&
(IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)))
- res->media_rc6 = read_rc6_residency("media_rc6");
+ res->media_rc6 = read_rc6_residency(dirfd, MEDIA_RC6_RESIDENCY_MS);
if (mask & RC6P_ENABLED)
- res->rc6p = read_rc6_residency("rc6p");
+ res->rc6p = read_rc6_residency(dirfd, RC6P_RESIDENCY_MS);
if (mask & RC6PP_ENABLED)
- res->rc6pp = read_rc6_residency("rc6pp");
+ res->rc6pp = read_rc6_residency(dirfd, RC6PP_RESIDENCY_MS);
res->duration += (gettime_ms() - res->duration) / 2;
}
-static void measure_residencies(int devid, unsigned int mask,
+static void measure_residencies(int devid, int dirfd, unsigned int mask,
struct residencies *res)
{
struct residencies start = { };
@@ -158,13 +158,13 @@ static void measure_residencies(int devid, unsigned int mask,
* measurement, since the valid counter range is different on
* different platforms and so fixing it up would be non-trivial.
*/
- read_residencies(devid, mask, &end);
+ read_residencies(devid, dirfd, mask, &end);
igt_debug("time=%d: rc6=(%d, %d), rc6p=%d, rc6pp=%d\n",
end.duration, end.rc6, end.media_rc6, end.rc6p, end.rc6pp);
for (retry = 0; retry < 2; retry++) {
start = end;
sleep(SLEEP_DURATION);
- read_residencies(devid, mask, &end);
+ read_residencies(devid, dirfd, mask, &end);
igt_debug("time=%d: rc6=(%d, %d), rc6p=%d, rc6pp=%d\n",
end.duration,
@@ -196,7 +196,7 @@ static void measure_residencies(int devid, unsigned int mask,
res->rc6 += res->rc6p;
}
-static bool wait_for_rc6(void)
+static bool wait_for_rc6(int dirfd)
{
struct timespec tv = {};
unsigned long start, now;
@@ -205,11 +205,11 @@ static bool wait_for_rc6(void)
usleep(160 * 1000);
/* Then poll for RC6 to start ticking */
- now = read_rc6_residency("rc6");
+ now = read_rc6_residency(dirfd, RC6_RESIDENCY_MS);
do {
start = now;
usleep(5000);
- now = read_rc6_residency("rc6");
+ now = read_rc6_residency(dirfd, RC6_RESIDENCY_MS);
if (now - start > 1)
return true;
} while (!igt_seconds_elapsed(&tv));
@@ -234,14 +234,27 @@ static uint64_t pmu_read_single(int fd)
return __pmu_read_single(fd, NULL);
}
-#define __assert_within_epsilon(x, ref, tol_up, tol_down) \
- igt_assert_f((x) <= (ref) * (1.0 + (tol_up)/100.) && \
- (x) >= (ref) * (1.0 - (tol_down)/100.), \
- "'%s' != '%s' (%.3g not within +%d%%/-%d%% tolerance of %.3g)\n",\
- #x, #ref, (double)(x), (tol_up), (tol_down), (double)(ref))
+#define __assert_within_epsilon(x, ref, tol_up, tol_down, debug_data) \
+ igt_assert_f((double)(x) <= (1.0 + (tol_up)) * (double)(ref) && \
+ (double)(x) >= (1.0 - (tol_down)) * (double)(ref), \
+ "'%s' != '%s' (%f not within +%.1f%%/-%.1f%% tolerance of %f)\n %s\n",\
+ #x, #ref, (double)(x), \
+ (tol_up) * 100.0, (tol_down) * 100.0, \
+ (double)(ref), debug_data)
+
+#define assert_within_epsilon(x, ref, tolerance, debug_data) \
+ __assert_within_epsilon(x, ref, tolerance, tolerance, debug_data)
-#define assert_within_epsilon(x, ref, tolerance) \
- __assert_within_epsilon(x, ref, tolerance, tolerance)
+char *drpc;
+
+static char *get_drpc(int i915, int gt_id)
+{
+ int gt_dir;
+
+ gt_dir = igt_debugfs_gt_dir(i915, gt_id);
+ igt_assert(gt_dir != -1);
+ return igt_sysfs_get(gt_dir, "drpc");
+}
static bool __pmu_wait_for_rc6(int fd)
{
@@ -376,7 +389,7 @@ static void kill_children(int sig)
signal(sig, old);
}
-static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags)
+static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags, unsigned int gt)
{
const int64_t duration_ns = SLEEP_DURATION * (int64_t)NSEC_PER_SEC;
const int tolerance = 20; /* Some RC6 is better than none! */
@@ -397,7 +410,7 @@ static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags)
struct igt_power gpu;
int fd;
- fd = open_pmu(i915, I915_PMU_RC6_RESIDENCY);
+ fd = open_pmu(i915, __I915_PMU_RC6_RESIDENCY(gt));
igt_drop_caches_set(i915, DROP_IDLE);
igt_require(__pmu_wait_for_rc6(fd));
igt_power_open(i915, &gpu, "gpu");
@@ -418,7 +431,10 @@ static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags)
"Total energy used while idle: %.1fmJ (%.1fmW)\n",
idle, (idle * 1e9) / slept);
}
- assert_within_epsilon(rc6, ts[1] - ts[0], 5);
+
+ drpc = get_drpc(i915, igt_sysfs_get_u32(gt, "id"));
+
+ assert_within_epsilon(rc6, ts[1] - ts[0], 5, drpc);
done = mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
@@ -454,7 +470,10 @@ static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags)
igt_assert(cycles >= SLEEP_DURATION);
/* While very nearly idle, expect full RC6 */
- assert_within_epsilon(rc6, ts[1] - ts[0], tolerance);
+ assert_within_epsilon(rc6, ts[1] - ts[0], tolerance, drpc);
+
+ free(drpc);
+ drpc = NULL;
}
munmap(done, 4096);
@@ -471,12 +490,13 @@ static void rc6_idle(int i915, uint32_t ctx_id, uint64_t flags)
}
}
-static void rc6_fence(int i915, const intel_ctx_t *ctx)
+static void rc6_fence(int i915, unsigned int gt)
{
const int64_t duration_ns = SLEEP_DURATION * (int64_t)NSEC_PER_SEC;
const int tolerance = 20; /* Some RC6 is better than none! */
const unsigned int gen = intel_gen(intel_get_drm_devid(i915));
const struct intel_execution_engine2 *e;
+ const intel_ctx_t *ctx;
struct power_sample sample[2];
unsigned long slept;
uint64_t rc6, ts[2], ahnd;
@@ -485,7 +505,7 @@ static void rc6_fence(int i915, const intel_ctx_t *ctx)
igt_require_sw_sync();
- fd = open_pmu(i915, I915_PMU_RC6_RESIDENCY);
+ fd = open_pmu(i915, __I915_PMU_RC6_RESIDENCY(gt));
igt_drop_caches_set(i915, DROP_IDLE);
igt_require(__pmu_wait_for_rc6(fd));
igt_power_open(i915, &gpu, "gpu");
@@ -506,9 +526,12 @@ static void rc6_fence(int i915, const intel_ctx_t *ctx)
"Total energy used while idle: %.1fmJ (%.1fmW)\n",
idle, (idle * 1e9) / slept);
}
- assert_within_epsilon(rc6, ts[1] - ts[0], 5);
+ drpc = get_drpc(i915, igt_sysfs_get_u32(gt, "id"));
+
+ assert_within_epsilon(rc6, ts[1] - ts[0], 5, drpc);
/* Submit but delay execution, we should be idle and conserving power */
+ ctx = intel_ctx_create_for_gt(i915, gt);
ahnd = get_reloc_ahnd(i915, ctx->id);
for_each_ctx_engine(i915, ctx, e) {
igt_spin_t *spin;
@@ -546,10 +569,14 @@ static void rc6_fence(int i915, const intel_ctx_t *ctx)
close(timeline);
- assert_within_epsilon(rc6, ts[1] - ts[0], tolerance);
+ assert_within_epsilon(rc6, ts[1] - ts[0], tolerance, drpc);
gem_quiescent_gpu(i915);
+
+ free(drpc);
+ drpc = NULL;
}
put_ahnd(ahnd);
+ intel_ctx_destroy(i915,ctx);
igt_power_close(&gpu);
close(fd);
@@ -558,6 +585,7 @@ static void rc6_fence(int i915, const intel_ctx_t *ctx)
igt_main
{
int i915 = -1;
+ unsigned int dirfd, gt;
const intel_ctx_t *ctx;
/* Use drm_open_driver to verify device existence */
@@ -572,19 +600,25 @@ igt_main
igt_require_gem(i915);
gem_quiescent_gpu(i915);
- for_each_ctx_engine(i915, ctx, e) {
- if (e->instance == 0) {
- igt_dynamic_f("%s", e->name)
- rc6_idle(i915, ctx->id, e->flags);
+ i915_for_each_gt(i915, dirfd, gt) {
+ ctx = intel_ctx_create_for_gt(i915, gt);
+ for_each_ctx_engine(i915, ctx, e) {
+ if (e->instance == 0) {
+ igt_dynamic_f("gt%u-%s", gt, e->name)
+ rc6_idle(i915, ctx->id, e->flags, gt);
+ }
}
+ intel_ctx_destroy(i915, ctx);
}
}
- igt_subtest("rc6-fence") {
+ igt_subtest_with_dynamic("rc6-fence") {
igt_require_gem(i915);
gem_quiescent_gpu(i915);
- rc6_fence(i915, ctx);
+ i915_for_each_gt(i915, dirfd, gt)
+ igt_dynamic_f("gt%u", gt)
+ rc6_fence(i915, gt);
}
igt_subtest_group {
@@ -595,21 +629,23 @@ igt_main
devid = intel_get_drm_devid(i915);
sysfs = igt_sysfs_open(i915);
- igt_require(has_rc6_residency("rc6"));
+ igt_require(has_rc6_residency(dirfd, RC6_RESIDENCY_MS));
/* Make sure rc6 counters are running */
igt_drop_caches_set(i915, DROP_IDLE);
- igt_require(wait_for_rc6());
+ igt_require(wait_for_rc6(dirfd));
rc6_enabled = get_rc6_enabled_mask();
igt_require(rc6_enabled & RC6_ENABLED);
}
igt_subtest("rc6-accuracy") {
- struct residencies res;
+ for_each_sysfs_gt_dirfd(i915, dirfd, gt) {
+ struct residencies res;
- measure_residencies(devid, rc6_enabled, &res);
- residency_accuracy(res.rc6, res.duration, "rc6");
+ measure_residencies(devid, dirfd, rc6_enabled, &res);
+ residency_accuracy(res.rc6, res.duration, "rc6");
+ }
}
igt_subtest("media-rc6-accuracy") {
@@ -617,7 +653,7 @@ igt_main
igt_require(IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid));
- measure_residencies(devid, rc6_enabled, &res);
+ measure_residencies(devid, sysfs, rc6_enabled, &res);
residency_accuracy(res.media_rc6, res.duration, "media_rc6");
}
@@ -626,7 +662,7 @@ igt_main
}
igt_fixture {
- intel_ctx_destroy(i915, ctx);
+ free(drpc);
drm_close_driver(i915);
}
}
--
2.25.1
More information about the igt-dev
mailing list