From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [PATCH i-g-t 3/5] lib/igt_power: Add power_supply/BAT based measurement
Date: Mon, 16 Sep 2024 23:18:39 +0300 [thread overview]
Message-ID: <20240916201841.29592-4-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20240916201841.29592-1-ville.syrjala@linux.intel.com>
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Allow measuring total system power via the power_supply class
stuff in sysfs (typically the information there comes from ACPI).
There are two types of batteries:
- reports remaining capacity in uWh (energy_now)
- reports remaining capacity in uAh (charge_now)
The first type is easier since we just have to convert to
uJ. The second type is less convenient since we also need
the voltage to determine energy. For that we just multiply
with voltage_now (in uV) when sampling charge_now. Obviously
this isn't entirely correct (should integrate instead), but
I think it's close enough to be useful.
Also one should keep in mind that the battery reports remaining
energy, not consumed energy. So we have to flip stuff around when
calculating things. Another alternative would be flip already
when measuring (eg. {charge,energy}_full_design - {charge,energy}_now),
but that seems more of a hassle really.
TODO: maybe confirm that the AC adapter is unplugged and the
battery is actually reporting to discharge before we start?
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
lib/igt_power.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/igt_power.h | 5 ++++-
2 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/lib/igt_power.c b/lib/igt_power.c
index e891da87acf3..a3e8ee588365 100644
--- a/lib/igt_power.c
+++ b/lib/igt_power.c
@@ -85,6 +85,21 @@ static inline void rapl_close(struct rapl *r)
r->fd = -1;
}
+static uint64_t bat_get_energy(int fd)
+{
+ if (igt_sysfs_has_attr(fd, "energy_now")) {
+ /* uWh -> uJ */
+ return 3600 *
+ igt_sysfs_get_u64(fd, "energy_now");
+ } else {
+ /* uAh * uV -> uJ */
+ return 3600 *
+ igt_sysfs_get_u64(fd, "charge_now") *
+ igt_sysfs_get_u64(fd, "voltage_now") /
+ 1000000;
+ }
+}
+
/**
* igt_power_open:
* @fd : device fd
@@ -103,6 +118,7 @@ int igt_power_open(int fd, struct igt_power *p, const char *domain)
int i;
p->hwmon_fd = -1;
+ p->bat_fd = -1;
p->rapl.fd = -1;
if (fd >= 0 && is_intel_dgfx(fd)) {
@@ -140,6 +156,8 @@ void igt_power_get_energy(struct igt_power *power, struct power_sample *s)
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->bat_fd >= 0) {
+ s->energy = bat_get_energy(power->bat_fd);
} else if (power->rapl.fd >= 0) {
rapl_read(&power->rapl, s);
}
@@ -160,6 +178,8 @@ double igt_power_get_mJ(const struct igt_power *power,
{
if (power->hwmon_fd >= 0)
return (p1->energy - p0->energy) * 1e-3;
+ else if (power->bat_fd >= 0)
+ return (p0->energy - p1->energy) * 1e-3; /* battery measures remaining energy */
else if (power->rapl.fd >= 0)
return ((p1->energy - p0->energy) * power->rapl.scale) * 1e3;
@@ -207,7 +227,47 @@ void igt_power_close(struct igt_power *power)
if (power->hwmon_fd >= 0) {
close(power->hwmon_fd);
power->hwmon_fd = -1;
+ } else if (power->bat_fd >= 0) {
+ close(power->bat_fd);
+ power->bat_fd = -1;
} else if (power->rapl.fd >= 0) {
rapl_close(&power->rapl);
}
}
+
+/**
+ * igt_power_bat_open:
+ * @igt_power : power struct
+ * @index: battery index
+ *
+ * opens the power_supply fd based on battery index
+ *
+ * Returns
+ * 0 on success, errno otherwise
+ */
+int igt_power_bat_open(struct igt_power *p, int index)
+{
+ char path[64];
+ int fd;
+
+ p->hwmon_fd = -1;
+ p->bat_fd = -1;
+ p->rapl.fd = -1;
+
+ snprintf(path, sizeof(path), "/sys/class/power_supply/BAT%d", index);
+
+ fd = open(path, O_RDONLY | O_DIRECTORY);
+ if (fd < 0)
+ return fd;
+
+ if (!igt_sysfs_has_attr(fd, "energy_now") &&
+ !(igt_sysfs_has_attr(fd, "charge_now") &&
+ igt_sysfs_has_attr(fd, "voltage_now"))) {
+ close(fd);
+ return -1;
+ }
+
+ p->bat_fd = fd;
+
+ return 0;
+}
diff --git a/lib/igt_power.h b/lib/igt_power.h
index 68a05300eec2..853b0fae815a 100644
--- a/lib/igt_power.h
+++ b/lib/igt_power.h
@@ -42,14 +42,17 @@ struct power_sample {
struct igt_power {
struct rapl rapl;
int hwmon_fd;
+ int bat_fd;
};
int igt_power_open(int i915, struct igt_power *p, const char *domain);
void igt_power_close(struct igt_power *p);
+int igt_power_bat_open(struct igt_power *p, int index);
+
static inline bool igt_power_valid(struct igt_power *p)
{
- return (p->rapl.fd >= 0) || (p->hwmon_fd >= 0);
+ return p->rapl.fd >= 0 || p->hwmon_fd >= 0 || p->bat_fd >= 0;
}
void igt_power_get_energy(struct igt_power *p, struct power_sample *s);
--
2.44.2
next prev parent reply other threads:[~2024-09-16 20:18 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-16 20:18 [PATCH i-g-t 0/5] Power/energy and display memory bandwidth measurement tools Ville Syrjala
2024-09-16 20:18 ` [PATCH i-g-t 1/5] lib/power: Allow use of rapl by specifying fd=-1 Ville Syrjala
2024-10-11 17:17 ` Kamil Konieczny
2024-10-14 16:57 ` Ville Syrjälä
2024-09-16 20:18 ` [PATCH i-g-t 2/5] igt: Use is_intel_dgfx() Ville Syrjala
2024-10-11 17:20 ` Kamil Konieczny
2024-09-16 20:18 ` Ville Syrjala [this message]
2024-10-11 17:30 ` [PATCH i-g-t 3/5] lib/igt_power: Add power_supply/BAT based measurement Kamil Konieczny
2024-10-14 17:07 ` Ville Syrjälä
2024-09-16 20:18 ` [PATCH i-g-t 4/5] tools/power: Introduce a small power/energy measurement tool Ville Syrjala
2024-10-11 17:39 ` Kamil Konieczny
2024-09-16 20:18 ` [PATCH i-g-t 5/5] tools/intel_display_bandwidth: Tool for measuring display memory bandwidth utilization Ville Syrjala
2024-10-11 17:52 ` Kamil Konieczny
2024-10-14 16:34 ` Ville Syrjälä
2025-02-26 15:39 ` Govindapillai, Vinod
2025-02-26 15:51 ` Ville Syrjälä
2025-02-26 16:23 ` Govindapillai, Vinod
2024-09-16 21:24 ` ✓ CI.xeBAT: success for Power/energy and display memory bandwidth measurement tools Patchwork
2024-09-16 21:40 ` ✓ Fi.CI.BAT: " Patchwork
2024-09-17 0:20 ` ✗ CI.xeFULL: failure " Patchwork
2024-09-17 11:05 ` ✗ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240916201841.29592-4-ville.syrjala@linux.intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox