summaryrefslogtreecommitdiff
path: root/tests/i915/gem_exec_suspend.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2019-10-27 16:15:55 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2019-10-30 12:49:28 +0000
commit922f28ad8843251adc6760e7f4b867f1d2b5104f (patch)
treee073c8e886b13495472a3e4ecc163b43455ce0c2 /tests/i915/gem_exec_suspend.c
parent6d30ec2314f22f465113f7a972944fee546ecbd9 (diff)
i915/gem_exec_suspend: Measure power consumption during suspend
For this test, we need a laptop running on battery power so that we can read the battery charge level before and after suspend. And then wait long enough for a reliable measure. References: https://bugs.freedesktop.org/show_bug.cgi?id=111909 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Acked-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Diffstat (limited to 'tests/i915/gem_exec_suspend.c')
-rw-r--r--tests/i915/gem_exec_suspend.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/tests/i915/gem_exec_suspend.c b/tests/i915/gem_exec_suspend.c
index af6190dd..eb28669c 100644
--- a/tests/i915/gem_exec_suspend.c
+++ b/tests/i915/gem_exec_suspend.c
@@ -27,9 +27,13 @@
* Exercise executing batches across suspend before checking the results.
*/
+#include <fcntl.h>
+#include <unistd.h>
+
#include "igt.h"
-#include "igt_gt.h"
#include "igt_dummyload.h"
+#include "igt_gt.h"
+#include "igt_sysfs.h"
#define NOSLEEP 0
#define IDLE 1
@@ -232,6 +236,61 @@ static void run_test(int fd, unsigned engine, unsigned flags)
test_all(fd, flags);
}
+struct battery_sample {
+ struct timespec tv;
+ uint64_t charge;
+};
+
+static bool get_power(int dir, struct battery_sample *s)
+{
+ return (clock_gettime(CLOCK_REALTIME, &s->tv) == 0 &&
+ igt_sysfs_scanf(dir, "charge_now", "%"PRIu64, &s->charge) == 1);
+}
+
+static double d_charge(const struct battery_sample *after,
+ const struct battery_sample *before)
+{
+ return (before->charge - after->charge) * 1e-3; /* mWh */
+}
+
+static double d_time(const struct battery_sample *after,
+ const struct battery_sample *before)
+{
+ return ((after->tv.tv_sec - before->tv.tv_sec) +
+ (after->tv.tv_nsec - before->tv.tv_nsec) * 1e-9); /* s */
+}
+
+static void power_test(int i915, unsigned engine, unsigned flags)
+{
+ struct battery_sample before, after;
+ char *status;
+ int dir;
+
+ dir = open("/sys/class/power_supply/BAT0", O_RDONLY);
+ igt_require_f(dir != -1, "/sys/class/power_supply/BAT0 not available\n");
+
+ igt_require_f(get_power(dir, &before),
+ "power test needs reported energy level\n");
+
+ status = igt_sysfs_get(dir, "status");
+ igt_require_f(status && strcmp(status, "Discharging") == 0,
+ "power test needs to be on battery, not mains, power\n");
+ free(status);
+
+ igt_set_autoresume_delay(5 * 60); /* 5 minutes; longer == more stable */
+
+ igt_assert(get_power(dir, &before));
+ run_test(i915, engine, flags);
+ igt_assert(get_power(dir, &after));
+
+ igt_set_autoresume_delay(0);
+
+ igt_info("Power consumed while suspended: %.3fmWh\n",
+ d_charge(&after, &before));
+ igt_info("Discharge rate while suspended: %.3fmW\n",
+ d_charge(&after, &before) * 3600 / d_time(&after, &before));
+}
+
igt_main
{
const struct {
@@ -289,6 +348,11 @@ igt_main
igt_subtest("hang-S4")
run_test(fd, 0, HIBERNATE | HANG);
+ igt_subtest("power-S0")
+ power_test(fd, 0, IDLE);
+ igt_subtest("power-S3")
+ power_test(fd, 0, SUSPEND);
+
igt_fixture {
igt_disallow_hang(fd, hang);
close(fd);