summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni.dodonov@intel.com>2011-11-07 21:11:31 -0200
committerEugeni Dodonov <eugeni.dodonov@intel.com>2011-11-09 11:46:10 -0200
commit8be217af2fc515f989dbdccbacbc06a758dfbc32 (patch)
tree9d50492abf57a72eda0710186a056a9ff3456808 /tools
parent4f206f743c660aece71d0ba09a29fcb24d071835 (diff)
intel_gpu_top: Grab i915-specific power values
This also adds initial support for unique fields naming, for more extensible parsing with intel_gpu_analyze. Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/intel_gpu_top.c85
1 files changed, 61 insertions, 24 deletions
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index cdf40d3..bcdb740 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -120,6 +120,7 @@ uint64_t last_stats[STATS_COUNT];
#ifdef HAVE_LINUX_FEATURES
#define BATTERY "BAT1"
+#define DEBUGFS "/sys/kernel/debug/dri/0/"
struct cpudata
{
@@ -134,9 +135,9 @@ struct proc_cpudata
struct powerdata
{
- long rate;
- long voltage;
float watts;
+ float watts_chipset;
+ float watts_gfx;
};
static void
@@ -166,20 +167,22 @@ get_battery_file(char *battery)
}
static void
-get_power_stat(struct powerdata *power, const char *battery_file)
+get_power_stat(struct powerdata *power, const char *battery_file, char *debugfs, float elapsed_time)
{
FILE *file;
char line[255];
+ long rate, voltage;
+
+ /* Reset values */
+ power->watts = power->watts_chipset = power->watts_gfx = -1;
file = fopen(battery_file, "r");
if (!file) {
/* Unable to read battery information */
- power->rate=-1;
- power->voltage=-1;
- power->watts=-1;
return;
}
- /* Sample /proc/acpi/battery/BAT?/state file format:
+ /* Reading ACPI-adquired power
+ * Sample /proc/acpi/battery/BAT?/state file format:
* present: yes
* capacity state: ok
* charging state: discharging
@@ -191,17 +194,45 @@ get_power_stat(struct powerdata *power, const char *battery_file)
fgets(line, 255, file);
fgets(line, 255, file);
fgets(line, 255, file);
- sscanf(line, "present rate:\t%lu mAh\n", &power->rate);
+ sscanf(line, "present rate:\t%lu mAh\n", &rate);
fgets(line, 255, file);
fgets(line, 255, file);
- sscanf(line, "present voltage:\t%lu mV\n", &power->voltage);
+ sscanf(line, "present voltage:\t%lu mV\n", &voltage);
fclose(file);
- power->watts = (float) (power->rate * power->voltage) / 1000000;
+
+ power->watts = (float) (rate * voltage) / 1000000;
+ power->watts *= elapsed_time;
+
+ /* Going deeper and reading GPU power */
+ if (debugfs) {
+ char debugfs_entry[128];
+ long tmp;
+ sprintf(debugfs_entry, "%s%s", debugfs, "i915_emon_status");
+ file = fopen(debugfs_entry, "r");
+ if (!file) {
+ /* Unable to read debugfs file */
+ return;
+ }
+ /* Reading i915 debugfs data
+ * Sample /sys/kernel/debug/dri/0/i915_emon_status file format:
+ * GMCH temp: 44
+ * Chipset power: 3063
+ * GFX power: 2393
+ * Total power: 5456
+ */
+ fgets(line, 255, file);
+ fgets(line, 255, file);
+ sscanf(line, "Chipset power: %lu\n", &tmp);
+ power->watts_chipset = (float) tmp / 1000;
+ fgets(line, 255, file);
+ sscanf(line, "GFX power: %lu\n", &tmp);
+ power->watts_gfx = (float) tmp / 1000;
+ }
}
static void linux_print_header(FILE *out)
{
- fprintf(out, "user%%\tsys%%\tpower(W)\t");
+ fprintf(out, "user%%\tsys%%\tpower.total\tpower.chipset\tpower.gfx\t");
}
static void linux_print(FILE *out, struct cpudata *cpu, struct cpudata *oldcpu,
@@ -210,8 +241,8 @@ static void linux_print(FILE *out, struct cpudata *cpu, struct cpudata *oldcpu,
float uload, sload;
uload = (float) ((cpu->user - oldcpu->user) * 100) / (cpu->total - oldcpu->total);
sload = (float) ((cpu->system - oldcpu->system) * 100) / (cpu->total - oldcpu->total);
- fprintf(out, "%.2f\t%.2f\t%.2f\t",
- uload, sload, power->watts);
+ fprintf(out, "%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t",
+ uload, sload, power->watts, power->watts_chipset, power->watts_gfx);
}
#endif
@@ -454,8 +485,9 @@ static void ring_sample(struct ring *ring)
static void ring_print_header(FILE *out, struct ring *ring)
{
- fprintf(out, "%.6s%%\tops\t",
- ring->name
+ fprintf(out, "%s%%\t%s.ops\t",
+ ring->name,
+ ring->name
);
}
@@ -538,6 +570,7 @@ int main(int argc, char **argv)
struct cpudata oldcpu, cpu;
struct powerdata power;
char *battery = BATTERY, *battery_file = NULL;
+ char *debugfs = DEBUGFS;
int do_perf=0;
char *perf_output=NULL;
#endif
@@ -561,8 +594,10 @@ int main(int argc, char **argv)
}
else {
output = fopen(optarg, "w");
+#if HAVE_LINUX_FEATURES
perf_output = (char *)malloc(strlen(optarg) + 5);
sprintf(perf_output, "%s.perf", optarg);
+#endif
}
if (!output)
{
@@ -739,14 +774,6 @@ int main(int argc, char **argv)
usleep(interval);
}
-#ifdef HAVE_LINUX_FEATURES
- /* CPU */
- get_cpu_stat(&cpu);
-
- /* Power */
- get_power_stat(&power, battery_file);
-#endif
-
if (HAS_STATS_REGS(devid)) {
for (i = 0; i < STATS_COUNT; i++) {
uint32_t stats_high, stats_low, stats_high_2;
@@ -777,6 +804,14 @@ int main(int argc, char **argv)
t2 = gettime();
elapsed_time += (t2 - t1) / 1000000.0;
+#ifdef HAVE_LINUX_FEATURES
+ /* CPU */
+ get_cpu_stat(&cpu);
+
+ /* Power */
+ get_power_stat(&power, battery_file, debugfs, elapsed_time);
+#endif
+
if (interactive) {
printf("%s", clear_screen);
print_clock_info(pci_dev);
@@ -825,7 +860,7 @@ int main(int argc, char **argv)
ring_print_header(output, &blt_ring);
for (i = 0; i < MAX_NUM_TOP_BITS; i++) {
if (i < STATS_COUNT && HAS_STATS_REGS(devid)) {
- fprintf(output, "%.6s\t",
+ fprintf(output, "%s\t",
stats_reg_names[i]
);
}
@@ -884,8 +919,10 @@ int main(int argc, char **argv)
fclose(output);
intel_register_access_fini();
+#if HAVE_LINUX_FEATURES
if (perf_output != NULL)
free(perf_output);
+#endif
return 0;
}