We can use our existing rapl interface that monitors gpu power, to also sample the other rapl domains such as package, cores and ram. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Andi Shyti <andi.shyti@xxxxxxxxx> --- lib/Makefile.sources | 4 +- lib/igt_gpu_power.c | 87 ----------------------------- lib/igt_rapl.c | 69 +++++++++++++++++++++++ lib/{igt_gpu_power.h => igt_rapl.h} | 69 ++++++++++++++++------- lib/meson.build | 2 +- tests/i915/gem_exec_schedule.c | 39 ++++++++----- tests/i915/gem_exec_whisper.c | 15 ++--- 7 files changed, 155 insertions(+), 130 deletions(-) delete mode 100644 lib/igt_gpu_power.c create mode 100644 lib/igt_rapl.c rename lib/{igt_gpu_power.h => igt_rapl.h} (52%) diff --git a/lib/Makefile.sources b/lib/Makefile.sources index cf094ab89..34e0c012d 100644 --- a/lib/Makefile.sources +++ b/lib/Makefile.sources @@ -33,8 +33,6 @@ lib_source_list = \ igt_edid.h \ igt_eld.c \ igt_eld.h \ - igt_gpu_power.c \ - igt_gpu_power.h \ igt_gt.c \ igt_gt.h \ igt_gvt.c \ @@ -49,6 +47,8 @@ lib_source_list = \ igt_primes.h \ igt_rand.c \ igt_rand.h \ + igt_rapl.c \ + igt_rapl.h \ igt_rc.h \ igt_stats.c \ igt_stats.h \ diff --git a/lib/igt_gpu_power.c b/lib/igt_gpu_power.c deleted file mode 100644 index 7092b75b3..000000000 --- a/lib/igt_gpu_power.c +++ /dev/null @@ -1,87 +0,0 @@ -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <locale.h> -#include <math.h> -#include <unistd.h> -#include <inttypes.h> - -#include "igt_gpu_power.h" -#include "igt_perf.h" -#include "igt_sysfs.h" - -struct rapl { - uint64_t power, type; - double scale; -}; - -static int rapl_parse(struct rapl *r) -{ - locale_t locale, oldlocale; - bool result; - int dir; - - memset(r, 0, sizeof(*r)); - - dir = open("/sys/devices/power", O_RDONLY); - if (dir < 0) - return -errno; - - /* Replace user environment with plain C to match kernel format */ - locale = newlocale(LC_ALL, "C", 0); - oldlocale = uselocale(locale); - - result = true; - result &= igt_sysfs_scanf(dir, "type", - "%"PRIu64, &r->type) == 1; - result &= igt_sysfs_scanf(dir, "events/energy-gpu", - "event=%"PRIx64, &r->power) == 1; - result &= igt_sysfs_scanf(dir, "events/energy-gpu.scale", - "%lf", &r->scale) == 1; - - uselocale(oldlocale); - freelocale(locale); - - close(dir); - - if (!result) - return -EINVAL; - - if (isnan(r->scale) || !r->scale) - return -ERANGE; - - return 0; -} - -int gpu_power_open(struct gpu_power *power) -{ - struct rapl r; - - power->fd = rapl_parse(&r); - if (power->fd < 0) - goto err; - - power->fd = igt_perf_open(r.type, r.power); - if (power->fd < 0) { - power->fd = -errno; - goto err; - } - - power->scale = r.scale; - - return 0; - -err: - errno = 0; - return power->fd; -} - -bool gpu_power_read(struct gpu_power *power, struct gpu_power_sample *s) -{ - return read(power->fd, s, sizeof(*s)) == sizeof(*s); -} - -void gpu_power_close(struct gpu_power *power) -{ - close(power->fd); -} diff --git a/lib/igt_rapl.c b/lib/igt_rapl.c new file mode 100644 index 000000000..03e492260 --- /dev/null +++ b/lib/igt_rapl.c @@ -0,0 +1,69 @@ +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <locale.h> +#include <math.h> +#include <unistd.h> +#include <inttypes.h> + +#include "igt_perf.h" +#include "igt_rapl.h" +#include "igt_sysfs.h" + +static int rapl_parse(struct rapl *r, const char *str) +{ + locale_t locale, oldlocale; + bool result = true; + char buf[128]; + int dir; + + memset(r, 0, sizeof(*r)); + + dir = open("/sys/devices/power", O_RDONLY); + if (dir < 0) + return -errno; + + /* Replace user environment with plain C to match kernel format */ + locale = newlocale(LC_ALL, "C", 0); + oldlocale = uselocale(locale); + + result &= igt_sysfs_scanf(dir, "type", "%"PRIu64, &r->type) == 1; + + snprintf(buf, sizeof(buf), "events/energy-%s", str); + result &= igt_sysfs_scanf(dir, buf, "event=%"PRIx64, &r->power) == 1; + + snprintf(buf, sizeof(buf), "events/energy-%s.scale", str); + result &= igt_sysfs_scanf(dir, buf, "%lf", &r->scale) == 1; + + uselocale(oldlocale); + freelocale(locale); + + close(dir); + + if (!result) + return -EINVAL; + + if (isnan(r->scale) || !r->scale) + return -ERANGE; + + return 0; +} + +int rapl_open(struct rapl *r, const char *domain) +{ + r->fd = rapl_parse(r, domain); + if (r->fd < 0) + goto err; + + r->fd = igt_perf_open(r->type, r->power); + if (r->fd < 0) { + r->fd = -errno; + goto err; + } + + return 0; + +err: + errno = 0; + return r->fd; +} diff --git a/lib/igt_gpu_power.h b/lib/igt_rapl.h similarity index 52% rename from lib/igt_gpu_power.h rename to lib/igt_rapl.h index a578a02a0..55c46198e 100644 --- a/lib/igt_gpu_power.h +++ b/lib/igt_rapl.h @@ -22,45 +22,74 @@ * */ -#ifndef IGT_GPU_POWER_H -#define IGT_GPU_POWER_H +#ifndef IGT_RAPL_H +#define IGT_RAPL_H #include <stdbool.h> #include <stdint.h> -struct gpu_power { - int fd; +struct rapl { + uint64_t power, type; double scale; + int fd; }; -struct gpu_power_sample { +struct power_sample { uint64_t energy; uint64_t time; }; -int gpu_power_open(struct gpu_power *power); -bool gpu_power_read(struct gpu_power *power, struct gpu_power_sample *s); -void gpu_power_close(struct gpu_power *power); +int rapl_open(struct rapl *r, const char *domain); + +static inline int cpu_power_open(struct rapl *r) +{ + return rapl_open(r, "cpu"); +} + +static inline int gpu_power_open(struct rapl *r) +{ + return rapl_open(r, "gpu"); +} + +static inline int pkg_power_open(struct rapl *r) +{ + return rapl_open(r, "pkg"); +} + +static inline int ram_power_open(struct rapl *r) +{ + return rapl_open(r, "ram"); +} + +static inline bool rapl_read(struct rapl *r, struct power_sample *s) +{ + return read(r->fd, s, sizeof(*s)) == sizeof(*s); +} + +static inline void rapl_close(struct rapl *r) +{ + close(r->fd); +} -static inline double gpu_power_J(const struct gpu_power *p, - const struct gpu_power_sample *p0, - const struct gpu_power_sample *p1) +static inline double power_J(const struct rapl *r, + const struct power_sample *p0, + const struct power_sample *p1) { - return (p1->energy - p0->energy) * p->scale; + return (p1->energy - p0->energy) * r->scale; } -static inline double gpu_power_s(const struct gpu_power *p, - const struct gpu_power_sample *p0, - const struct gpu_power_sample *p1) +static inline double power_s(const struct rapl *r, + const struct power_sample *p0, + const struct power_sample *p1) { return (p1->time - p0->time) * 1e-9; } -static inline double gpu_power_W(const struct gpu_power *p, - const struct gpu_power_sample *p0, - const struct gpu_power_sample *p1) +static inline double power_W(const struct rapl *r, + const struct power_sample *p0, + const struct power_sample *p1) { - return gpu_power_J(p, p0, p1) / gpu_power_s(p, p0, p1); + return power_J(r, p0, p1) / power_s(r, p0, p1); } -#endif /* IGT_GPU_POWER_H */ +#endif /* IGT_RAPL_H */ diff --git a/lib/meson.build b/lib/meson.build index 221ae28c0..fbc0c8d14 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -11,7 +11,6 @@ lib_sources = [ 'igt_debugfs.c', 'igt_device.c', 'igt_aux.c', - 'igt_gpu_power.c', 'igt_gt.c', 'igt_gvt.c', 'igt_halffloat.c', @@ -19,6 +18,7 @@ lib_sources = [ 'igt_perf.c', 'igt_primes.c', 'igt_rand.c', + 'igt_rapl.c', 'igt_stats.c', 'igt_syncobj.c', 'igt_sysfs.c', diff --git a/tests/i915/gem_exec_schedule.c b/tests/i915/gem_exec_schedule.c index ddcb1f21a..9a2f2352b 100644 --- a/tests/i915/gem_exec_schedule.c +++ b/tests/i915/gem_exec_schedule.c @@ -29,8 +29,8 @@ #include <signal.h> #include "igt.h" -#include "igt_gpu_power.h" #include "igt_rand.h" +#include "igt_rapl.h" #include "igt_sysfs.h" #include "igt_vgem.h" #include "i915/gem_ring.h" @@ -1608,14 +1608,16 @@ static void test_pi_ringfull(int fd, unsigned int engine) static void measure_semaphore_power(int i915) { - struct gpu_power power; unsigned int engine, signaler; + struct rapl gpu, pkg; - igt_require(gpu_power_open(&power) == 0); + igt_require(pkg_power_open(&pkg) == 0); + igt_require(gpu_power_open(&gpu) == 0); for_each_physical_engine(i915, signaler) { - struct gpu_power_sample s_spin[2]; - struct gpu_power_sample s_sema[2]; + struct { + struct power_sample pkg, gpu; + } s_spin[2], s_sema[2]; double baseline, total; int64_t jiffie = 1; igt_spin_t *spin; @@ -1626,9 +1628,11 @@ static void measure_semaphore_power(int i915) gem_wait(i915, spin->handle, &jiffie); /* waitboost */ igt_spin_busywait_until_started(spin); - gpu_power_read(&power, &s_spin[0]); + rapl_read(&pkg, &s_spin[0].pkg); + rapl_read(&gpu, &s_spin[0].gpu); usleep(100*1000); - gpu_power_read(&power, &s_spin[1]); + rapl_read(&gpu, &s_spin[1].gpu); + rapl_read(&pkg, &s_spin[1].pkg); /* Add a waiter to each engine */ for_each_physical_engine(i915, engine) { @@ -1645,23 +1649,32 @@ static void measure_semaphore_power(int i915) } usleep(10); /* just give the tasklets a chance to run */ - gpu_power_read(&power, &s_sema[0]); + rapl_read(&pkg, &s_sema[0].pkg); + rapl_read(&gpu, &s_sema[0].gpu); usleep(100*1000); - gpu_power_read(&power, &s_sema[1]); + rapl_read(&gpu, &s_sema[1].gpu); + rapl_read(&pkg, &s_sema[1].pkg); igt_spin_free(i915, spin); - baseline = gpu_power_W(&power, &s_spin[0], &s_spin[1]); - total = gpu_power_W(&power, &s_sema[0], &s_sema[1]); - + baseline = power_W(&gpu, &s_spin[0].gpu, &s_spin[1].gpu); + total = power_W(&gpu, &s_sema[0].gpu, &s_sema[1].gpu); igt_info("%s: %.1fmW + %.1fmW (total %1.fmW)\n", e__->name, 1e3 * baseline, 1e3 * (total - baseline), 1e3 * total); + + baseline = power_W(&pkg, &s_spin[0].pkg, &s_spin[1].pkg); + total = power_W(&pkg, &s_sema[0].pkg, &s_sema[1].pkg); + igt_info("pkg: %.1fmW + %.1fmW (total %1.fmW)\n", + 1e3 * baseline, + 1e3 * (total - baseline), + 1e3 * total); } - gpu_power_close(&power); + rapl_close(&gpu); + rapl_close(&pkg); } igt_main diff --git a/tests/i915/gem_exec_whisper.c b/tests/i915/gem_exec_whisper.c index de7a14dad..1135c6497 100644 --- a/tests/i915/gem_exec_whisper.c +++ b/tests/i915/gem_exec_whisper.c @@ -29,7 +29,7 @@ #include "igt.h" #include "igt_debugfs.h" -#include "igt_gpu_power.h" +#include "igt_rapl.h" #include "igt_gt.h" #include "igt_rand.h" #include "igt_sysfs.h" @@ -186,8 +186,8 @@ static void whisper(int fd, unsigned engine, unsigned flags) unsigned int reloc_migrations = 0; unsigned int reloc_interruptions = 0; unsigned int eb_migrations = 0; - struct gpu_power_sample sample[2]; - struct gpu_power power; + struct power_sample sample[2]; + struct rapl rapl; uint64_t old_offset; int i, n, loc; int debugfs; @@ -199,7 +199,7 @@ static void whisper(int fd, unsigned engine, unsigned flags) } debugfs = igt_debugfs_dir(fd); - gpu_power_open(&power); + gpu_power_open(&rapl); nengine = 0; if (engine == ALL_ENGINES) { @@ -234,7 +234,7 @@ static void whisper(int fd, unsigned engine, unsigned flags) nchild *= nengine; intel_detect_and_clear_missed_interrupts(fd); - gpu_power_read(&power, &sample[0]); + rapl_read(&rapl, &sample[0]); igt_fork(child, nchild) { unsigned int pass; @@ -510,11 +510,12 @@ static void whisper(int fd, unsigned engine, unsigned flags) fini_hang(&hang); else igt_assert_eq(intel_detect_and_clear_missed_interrupts(fd), 0); - if (gpu_power_read(&power, &sample[1])) { + if (rapl_read(&rapl, &sample[1])) { igt_info("Total energy used: %.1fmJ\n", - gpu_power_J(&power, &sample[0], &sample[1]) * 1e3); + power_J(&rapl, &sample[0], &sample[1]) * 1e3); } + rapl_close(&rapl); close(debugfs); } -- 2.23.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx