diff options
author | Eugeni Dodonov <eugeni.dodonov@intel.com> | 2011-11-07 21:11:31 -0200 |
---|---|---|
committer | Eugeni Dodonov <eugeni.dodonov@intel.com> | 2011-11-09 11:46:10 -0200 |
commit | 8be217af2fc515f989dbdccbacbc06a758dfbc32 (patch) | |
tree | 9d50492abf57a72eda0710186a056a9ff3456808 /tools | |
parent | 4f206f743c660aece71d0ba09a29fcb24d071835 (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.c | 85 |
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; } |