Eventually the GPU_POWER sensor will be rated at around
50Hz but that's still too slow to read from the main loop of
umr's --top so we move all sensor operations to a thread.

Signed-off-by: Tom St Denis <[email protected]>
---
 src/app/top.c | 110 +++++++++++++++++++++++++++++-----------------------------
 1 file changed, 55 insertions(+), 55 deletions(-)

diff --git a/src/app/top.c b/src/app/top.c
index 74ae5dfbb98a..dedad93f029c 100644
--- a/src/app/top.c
+++ b/src/app/top.c
@@ -279,17 +279,35 @@ static struct umr_bitfield stat_drm_bits[] = {
 static FILE *logfile = NULL;
 
 static volatile int sensor_thread_quit = 0;
-static uint32_t gpu_power_data[4];
-static void *vi_sensor_thread(void *data)
+static volatile uint32_t gpu_power_data[32];
+static volatile struct umr_bitfield *sensor_bits = NULL;
+static void *gpu_sensor_thread(void *data)
 {
        struct umr_asic asic = *((struct umr_asic*)data);
-       int size = sizeof(gpu_power_data);
+       int size, rem, off, x;
        char fname[128];
 
        snprintf(fname, sizeof(fname)-1, 
"/sys/kernel/debug/dri/%d/amdgpu_sensors", asic.instance);
        asic.fd.sensors = open(fname, O_RDWR);
-       while (!sensor_thread_quit)
-               umr_read_sensor(&asic, AMDGPU_PP_SENSOR_GPU_POWER, 
gpu_power_data, &size);
+       while (!sensor_thread_quit) {
+               rem = sizeof gpu_power_data;
+               off = 0;
+               for (x = 0; sensor_bits[x].regname; ) {
+                       switch (sensor_bits[x].start) {
+                               case AMDGPU_PP_SENSOR_GPU_POWER:
+                                       size = 16;
+                                       break;
+                               default:
+                                       size = 4;
+                                       break;
+                       }
+                       if (size < rem)
+                               umr_read_sensor(&asic, sensor_bits[x].start, 
(uint32_t*)&gpu_power_data[off], &size);
+                       off += size / 4;
+                       rem -= size;
+                       x   += size / 4;
+               }
+       }
        close(asic.fd.sensors);
        return NULL;
 }
@@ -536,8 +554,8 @@ static void parse_bits(struct umr_asic *asic, uint32_t 
addr, struct umr_bitfield
 
 static void parse_sensors(struct umr_asic *asic, uint32_t addr, struct 
umr_bitfield *bits, uint64_t *counts, uint32_t *mask, uint32_t *cmp, uint64_t 
addr_mask)
 {
-       int j, size, x;
-       uint32_t value[16];
+       int j, x;
+       uint32_t value;
 
        (void)addr;
        (void)mask;
@@ -547,42 +565,29 @@ static void parse_sensors(struct umr_asic *asic, uint32_t 
addr, struct umr_bitfi
        if (asic->fd.sensors < 0)
                return;
 
-       for (j = 0; bits[j].regname; ) {
-               size = 4;
-               if (bits[j].start == AMDGPU_PP_SENSOR_GPU_POWER || 
!umr_read_sensor(asic, bits[j].start, &value[0], &size)) {
-                       x = 0;
-                       if (bits[j].start == AMDGPU_PP_SENSOR_GPU_POWER) {
-                               size = 4 * sizeof(uint32_t);
-                               memcpy(value, gpu_power_data, size);
-                       }
-
-                       while (size) {
-                               switch (bits[j].stop & 0x0F) {
-                                       case SENSOR_IDENTITY:
-                                               counts[j] = value[x];
-                                               break;
-                                       case SENSOR_D1000:
-                                               counts[j] = value[x] / 1000;
-                                               break;
-                                       case SENSOR_D100:
-                                               counts[j] = value[x] / 100;
-                                               break;
-                                       case SENSOR_WATT:
-                                               counts[j] = ((value[x] >> 8) * 
1000);
-                                               if ((value[x] & 0xFF) < 100)
-                                                       counts[j] += (value[x] 
& 0xFF) * 10;
-                                               else
-                                                       counts[j] += value[x];
-                                               counts[j] /= 10; // convert to 
centiwatts since we don't need 3 digits of excess precision
-                                               break;
-                               }
-                               size -= 4;
-                               ++j;
-                               ++x;
-                       }
-               } else {
-                       ++j;
+       for (x = j = 0; bits[j].regname; ) {
+               value = gpu_power_data[x];
+               switch (bits[j].stop & 0x0F) {
+                       case SENSOR_IDENTITY:
+                               counts[j] = value;
+                               break;
+                       case SENSOR_D1000:
+                               counts[j] = value / 1000;
+                               break;
+                       case SENSOR_D100:
+                               counts[j] = value / 100;
+                               break;
+                       case SENSOR_WATT:
+                               counts[j] = ((value >> 8) * 1000);
+                               if ((value & 0xFF) < 100)
+                                       counts[j] += (value & 0xFF) * 10;
+                               else
+                                       counts[j] += value;
+                               counts[j] /= 10; // convert to centiwatts since 
we don't need 3 digits of excess precision
+                               break;
                }
+               ++j;
+               ++x;
        }
 }
 
@@ -805,6 +810,7 @@ static void top_build_vi_program(struct umr_asic *asic)
                // SI
                ENTRY_SENSOR(i++, "GFX_SCLK", &stat_si_sensor_bits[0], 
&top_options.vi.sensors, "Sensors");
        }
+       sensor_bits = stat_counters[i-1].bits;
 
        // More GFX bits
        ENTRY(i++, "mmTA_STATUS", &stat_ta_bits[0], &top_options.vi.ta, "TA");
@@ -899,7 +905,7 @@ static void toggle_logger(void)
 
 void umr_top(struct umr_asic *asic)
 {
-       int i, j, k, use_thread;
+       int i, j, k;
        struct timespec req;
        uint32_t rep;
        time_t tt;
@@ -927,15 +933,11 @@ void umr_top(struct umr_asic *asic)
                        grab_bits(stat_counters[i].name, asic, 
stat_counters[i].bits, &stat_counters[i].addr);
 
        sensor_thread_quit = 0;
-       use_thread = 0;
 
-       // start thread to grab sensor data for VI
-       if (asic->family == FAMILY_VI) {
-               if (pthread_create(&sensor_thread, NULL, vi_sensor_thread, 
asic)) {
-                       fprintf(stderr, "[ERROR] Cannot create 
vi_sensor_thread\n");
-                       return;
-               }
-               use_thread = 1;
+       // start thread to grab sensor data
+       if (pthread_create(&sensor_thread, NULL, gpu_sensor_thread, asic)) {
+               fprintf(stderr, "[ERROR] Cannot create gpu_sensor_thread\n");
+               return;
        }
 
        initscr();
@@ -1068,8 +1070,6 @@ void umr_top(struct umr_asic *asic)
        }
        endwin();
 
-       if (use_thread) {
-               sensor_thread_quit = 1;
-               pthread_join(sensor_thread, NULL);
-       }
+       sensor_thread_quit = 1;
+       pthread_join(sensor_thread, NULL);
 }
-- 
2.12.0

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to