[igt-dev] [PATCH i-g-t 3/6] lib/igt_power: Add hwmon interface to igt_power
Riana Tauro
riana.tauro at intel.com
Tue Sep 6 10:38:15 UTC 2022
Modify igt_power to expose functions to read energy, power
using hwmon and rapl interface
Cc: Ashutosh Dixit <ashutosh.dixit at intel.com>
Signed-off-by: Riana Tauro <riana.tauro at intel.com>
---
lib/igt_power.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++-
lib/igt_power.h | 70 ++++++-----------------
2 files changed, 160 insertions(+), 54 deletions(-)
diff --git a/lib/igt_power.c b/lib/igt_power.c
index 814ad556..3b34be40 100644
--- a/lib/igt_power.c
+++ b/lib/igt_power.c
@@ -6,10 +6,14 @@
#include <unistd.h>
#include <inttypes.h>
+#include "igt.h"
+#include "igt_hwmon.h"
#include "igt_perf.h"
#include "igt_power.h"
#include "igt_sysfs.h"
+static const char *rapl_domains[] = { "cpu", "gpu", "pkg", "ram" };
+
static int rapl_parse(struct rapl *r, const char *str)
{
locale_t locale, oldlocale;
@@ -49,7 +53,7 @@ static int rapl_parse(struct rapl *r, const char *str)
return 0;
}
-int rapl_open(struct rapl *r, const char *domain)
+static int rapl_open(struct rapl *r, const char *domain)
{
r->fd = rapl_parse(r, domain);
if (r->fd < 0)
@@ -67,3 +71,141 @@ err:
errno = 0;
return r->fd;
}
+
+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);
+ r->fd = -1;
+}
+
+/**
+ * igt_power_open:
+ * @fd : device fd
+ * @igt_power : power struct
+ * @domain: rapl domain
+ *
+ * opens the hwmon/rapl fd based on domain
+ * hwmon fd - domain gpu -dgfx
+ * rapl fd - all domains - igfx
+ *
+ * Returns
+ * 0 on success, errno otherwise
+ */
+int igt_power_open(int fd, struct igt_power *p, const char *domain)
+{
+ int i;
+
+ p->hwmon_fd = -1;
+ p->rapl.fd = -1;
+
+ if (gem_has_lmem(fd)) {
+ if (strncmp(domain, "gpu", strlen("gpu")) == 0) {
+ p->hwmon_fd = igt_hwmon_open(fd);
+ if (p->hwmon_fd >= 0)
+ return 0;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(rapl_domains); i++)
+ if (strncmp(domain, rapl_domains[i], strlen(rapl_domains[i])) == 0)
+ return rapl_open(&p->rapl, domain);
+ }
+
+ return -EINVAL;
+}
+
+/**
+ * igt_power_get_energy:
+ * @igt_power : power struct
+ * @power_sample: sample of energy and time
+ *
+ * Reads energy from hwmon if energy1_input file is present, else read
+ * from rapl interface
+ *
+ */
+void igt_power_get_energy(struct igt_power *power, struct power_sample *s)
+{
+ struct timespec ts;
+
+ s->energy = 0;
+ igt_assert(!clock_gettime(CLOCK_MONOTONIC, &ts));
+ s->time = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
+
+ if (power->hwmon_fd >= 0) {
+ if (igt_sysfs_has_attr(power->hwmon_fd, "energy1_input"))
+ s->energy = igt_sysfs_get_u64(power->hwmon_fd, "energy1_input");
+ } else if (power->rapl.fd >= 0) {
+ rapl_read(&power->rapl, s);
+ }
+}
+
+/**
+ * igt_power_get_mJ:
+ * @igt_power : power struct
+ * @power_sample: sample of energy and time
+ *
+ * Calculates energy difference between two power samples
+ *
+ * Returns
+ * energy in mJ from hwmon/rapl
+ */
+double igt_power_get_mJ(const struct igt_power *power,
+ const struct power_sample *p0, const struct power_sample *p1)
+{
+ if (power->hwmon_fd >= 0)
+ return (p1->energy - p0->energy) * 1e-3;
+ else if (power->rapl.fd >= 0)
+ return ((p1->energy - p0->energy) * power->rapl.scale) * 1e3;
+
+ return 0;
+}
+
+/**
+ * igt_power_get_mW:
+ * @igt_power : power struct
+ * @power_sample: sample of energy and time
+ *
+ * Calculates power
+ *
+ * Returns
+ * power in milliWatts
+ */
+double igt_power_get_mW(const struct igt_power *power,
+ const struct power_sample *p0, const struct power_sample *p1)
+{
+ return igt_power_get_mJ(power, p0, p1) / igt_power_get_s(p0, p1);
+}
+
+/**
+ * igt_power_get_s:
+ * @power_sample: sample of energy and time
+ *
+ * Returns
+ * time differnce in seconds
+ */
+double igt_power_get_s(const struct power_sample *p0,
+ const struct power_sample *p1)
+{
+ return (p1->time - p0->time) * 1e-9;
+}
+
+/**
+ * igt_power_close:
+ * @igt_power : power struct
+ *
+ * closes hwmon/rapl fd
+ *
+ */
+void igt_power_close(struct igt_power *power)
+{
+ if (power->hwmon_fd >= 0) {
+ close(power->hwmon_fd);
+ power->hwmon_fd = -1;
+ } else if (power->rapl.fd >= 0) {
+ rapl_close(&power->rapl);
+ }
+}
diff --git a/lib/igt_power.h b/lib/igt_power.h
index 11ddcdee..68a05300 100644
--- a/lib/igt_power.h
+++ b/lib/igt_power.h
@@ -39,63 +39,27 @@ struct power_sample {
uint64_t time;
};
-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 bool rapl_valid(struct rapl *r)
-{
- return r->fd >= 0;
-}
-
-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);
- r->fd = -1;
-}
+struct igt_power {
+ struct rapl rapl;
+ int hwmon_fd;
+};
-static inline double power_J(const struct rapl *r,
- const struct power_sample *p0,
- const struct power_sample *p1)
-{
- return (p1->energy - p0->energy) * r->scale;
-}
+int igt_power_open(int i915, struct igt_power *p, const char *domain);
+void igt_power_close(struct igt_power *p);
-static inline double power_s(const struct rapl *r,
- const struct power_sample *p0,
- const struct power_sample *p1)
+static inline bool igt_power_valid(struct igt_power *p)
{
- return (p1->time - p0->time) * 1e-9;
+ return (p->rapl.fd >= 0) || (p->hwmon_fd >= 0);
}
-static inline double power_W(const struct rapl *r,
- const struct power_sample *p0,
- const struct power_sample *p1)
-{
- return power_J(r, p0, p1) / power_s(r, p0, p1);
-}
+void igt_power_get_energy(struct igt_power *p, struct power_sample *s);
+double igt_power_get_mJ(const struct igt_power *power,
+ const struct power_sample *p0,
+ const struct power_sample *p1);
+double igt_power_get_mW(const struct igt_power *power,
+ const struct power_sample *p0,
+ const struct power_sample *p1);
+double igt_power_get_s(const struct power_sample *p0,
+ const struct power_sample *p1);
#endif /* IGT_POWER_H */
--
2.25.1
More information about the igt-dev
mailing list