Read the RAPL power metrics courtesy of perf. Or your local HW equivalent? v2: uselocale() v3: Use gpu_power_s(), gpu_power_J(), gpu_power_W() to try and make the scale factors self-consistent. v4: Use igt_sysfs Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> --- lib/Makefile.am | 1 + lib/Makefile.sources | 2 ++ lib/igt_gpu_power.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ lib/igt_gpu_power.h | 66 +++++++++++++++++++++++++++++++++++++ lib/meson.build | 2 ++ 5 files changed, 149 insertions(+) create mode 100644 lib/igt_gpu_power.c create mode 100644 lib/igt_gpu_power.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 3e6a7fdba..62e8bda73 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -84,4 +84,5 @@ libintel_tools_la_LIBADD = \ $(LIBUDEV_LIBS) \ $(PIXMAN_LIBS) \ $(GLIB_LIBS) \ + libigt_perf.la \ -lm diff --git a/lib/Makefile.sources b/lib/Makefile.sources index cf2720981..e00347f94 100644 --- a/lib/Makefile.sources +++ b/lib/Makefile.sources @@ -26,6 +26,8 @@ lib_source_list = \ igt_color_encoding.c \ igt_color_encoding.h \ igt_edid_template.h \ + igt_gpu_power.c \ + igt_gpu_power.h \ igt_gt.c \ igt_gt.h \ igt_gvt.c \ diff --git a/lib/igt_gpu_power.c b/lib/igt_gpu_power.c new file mode 100644 index 000000000..61842e17e --- /dev/null +++ b/lib/igt_gpu_power.c @@ -0,0 +1,78 @@ +#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; + int dir; + + 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); + + memset(r, 0, sizeof(*r)); + igt_sysfs_scanf(dir, "type", "%"PRIu64, &r->type); + igt_sysfs_scanf(dir, "events/energy-gpu", "event=%"PRIx64, &r->power); + igt_sysfs_scanf(dir, "events/energy-gpu.scale", "%lf", &r->scale); + + uselocale(oldlocale); + freelocale(locale); + + close(dir); + + if (isnan(r->scale) || !r->scale) + return -EINVAL; + + 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_gpu_power.h b/lib/igt_gpu_power.h new file mode 100644 index 000000000..032e48b11 --- /dev/null +++ b/lib/igt_gpu_power.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2019 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#ifndef IGT_GPU_POWER_H +#define IGT_GPU_POWER_H + +#include <stdbool.h> +#include <stdint.h> + +struct gpu_power { + int fd; + double scale; +}; + +struct gpu_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); + +static inline double gpu_power_J(const struct gpu_power *p, + const struct gpu_power_sample *t0, + const struct gpu_power_sample *t1) +{ + return (t1->energy - t0->energy) * p->scale; +} + +static inline double gpu_power_s(const struct gpu_power *p, + const struct gpu_power_sample *t0, + const struct gpu_power_sample *t1) +{ + return (t1->time - t0->time) * 1e-9; +} + +static inline double gpu_power_W(const struct gpu_power *p, + const struct gpu_power_sample *t0, + const struct gpu_power_sample *t1) +{ + return gpu_power_J(p, t0, t1) / gpu_power_s(p, t0, t1); +} + +#endif /* IGT_GPU_POWER_H */ diff --git a/lib/meson.build b/lib/meson.build index 0eb5585d7..89de06e69 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -9,9 +9,11 @@ lib_sources = [ 'igt_debugfs.c', 'igt_device.c', 'igt_aux.c', + 'igt_gpu_power.c', 'igt_gt.c', 'igt_gvt.c', 'igt_matrix.c', + 'igt_perf.c', 'igt_primes.c', 'igt_rand.c', 'igt_stats.c', -- 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx