1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-09-29 21:49:07 +00:00

made fan data available for indices higher than the gpu card count, and added some protection against bad requests

This commit is contained in:
humanoid2050 2020-09-25 15:46:33 -04:00 committed by Brenden Matthews
parent b679b54508
commit 351a7a8d22

View File

@ -40,55 +40,55 @@
* *
* Showcase (conky.conf): * Showcase (conky.conf):
* --==| NVIDIA | ==-- * --==| NVIDIA | ==--
* GPU ${nvidia gpufreq [gpu_id]}MHz (${nvidia gpufreqmin [gpu_id]}-${nvidia * GPU ${nvidia gpufreq [target_id]}MHz (${nvidia gpufreqmin [target_id]}-${nvidia
* gpufreqmax [gpu_id]}MHz) MEM ${nvidia memfreq [gpu_id]}MHz (${nvidia * gpufreqmax [target_id]}MHz) MEM ${nvidia memfreq [target_id]}MHz (${nvidia
* memfreqmin [gpu_id]}-${nvidia memfreqmax [gpu_id]}MHz) MTR ${nvidia * memfreqmin [target_id]}-${nvidia memfreqmax [target_id]}MHz) MTR ${nvidia
* mtrfreq [gpu_id]}MHz (${nvidia mtrfreqmin [gpu_id]}-${nvidia mtrfreqmax * mtrfreq [target_id]}MHz (${nvidia mtrfreqmin [target_id]}-${nvidia mtrfreqmax
* [gpu_id]}MHz) PERF Level ${nvidia perflevel [gpu_id]} (${nvidia * [target_id]}MHz) PERF Level ${nvidia perflevel [target_id]} (${nvidia
* perflevelmin [gpu_id]}-${nvidia perflevelmax [gpu_id]}), Mode: ${nvidia * perflevelmin [target_id]}-${nvidia perflevelmax [target_id]}), Mode: ${nvidia
* perfmode [gpu_id]} VRAM ${nvidia memutil [gpu_id]}% (${nvidia memused * perfmode [target_id]} VRAM ${nvidia memutil [target_id]}% (${nvidia memused
* [gpu_id]}MB/${nvidia memtotal [gpu_id]}MB) LOAD GPU ${nvidia gpuutil * [target_id]}MB/${nvidia memtotal [target_id]}MB) LOAD GPU ${nvidia gpuutil
* [gpu_id]}%, RAM ${nvidia membwutil [gpu_id]}%, VIDEO ${nvidia videoutil * [target_id]}%, RAM ${nvidia membwutil [target_id]}%, VIDEO ${nvidia videoutil
* [gpu_id]}%, PCIe ${nvidia pcieutil [gpu_id]}% TEMP GPU ${nvidia gputemp * [target_id]}%, PCIe ${nvidia pcieutil [target_id]}% TEMP GPU ${nvidia gputemp
* [gpu_id]}°C (${nvidia gputempthreshold [gpu_id]}°C max.), SYS ${nvidia * [target_id]}°C (${nvidia gputempthreshold [target_id]}°C max.), SYS ${nvidia
* ambienttemp [gpu_id]}°C FAN ${nvidia fanspeed [gpu_id]} RPM (${nvidia * ambienttemp [target_id]}°C FAN ${nvidia fanspeed [target_id]} RPM (${nvidia
* fanlevel [gpu_id]}%) * fanlevel [target_id]}%)
* *
* Miscellaneous: * Miscellaneous:
* OPENGL ${nvidia imagequality [gpu_id]} * OPENGL ${nvidia imagequality [target_id]}
* GPU ${nvidia modelname [gpu_id]} * GPU ${nvidia modelname [target_id]}
* DRIVER ${nvidia driverversion [gpu_id]} * DRIVER ${nvidia driverversion [target_id]}
* *
* --==| NVIDIA Bars |==-- * --==| NVIDIA Bars |==--
* LOAD ${nvidiabar [height][,width] gpuutil [gpu_id]} * LOAD ${nvidiabar [height][,width] gpuutil [target_id]}
* VRAM ${nvidiabar [height][,width] memutil [gpu_id]} * VRAM ${nvidiabar [height][,width] memutil [target_id]}
* RAM ${nvidiabar [height][,width] membwutil [gpu_id]} * RAM ${nvidiabar [height][,width] membwutil [target_id]}
* VIDEO ${nvidiabar [height][,width] videoutil [gpu_id]} * VIDEO ${nvidiabar [height][,width] videoutil [target_id]}
* PCIe ${nvidiabar [height][,width] pcieutil [gpu_id]} * PCIe ${nvidiabar [height][,width] pcieutil [target_id]}
* Fan ${nvidiabar [height][,width] fanlevel [gpu_id]} * Fan ${nvidiabar [height][,width] fanlevel [target_id]}
* TEMP ${nvidiabar [height][,width] gputemp [gpu_id]} * TEMP ${nvidiabar [height][,width] gputemp [target_id]}
* *
* --==| NVIDIA Gauge |==-- * --==| NVIDIA Gauge |==--
* LOAD ${nvidiagauge [height][,width] gpuutil [gpu_id]} * LOAD ${nvidiagauge [height][,width] gpuutil [target_id]}
* VRAM ${nvidiagauge [height][,width] memutil [gpu_id]} * VRAM ${nvidiagauge [height][,width] memutil [target_id]}
* RAM ${nvidiagauge [height][,width] membwutil [gpu_id]} * RAM ${nvidiagauge [height][,width] membwutil [target_id]}
* VIDEO ${nvidiagauge [height][,width] videoutil [gpu_id]} * VIDEO ${nvidiagauge [height][,width] videoutil [target_id]}
* PCIe ${nvidiagauge [height][,width] pcieutil [gpu_id]} * PCIe ${nvidiagauge [height][,width] pcieutil [target_id]}
* Fan ${nvidiagauge [height][,width] fanlevel [gpu_id]} * Fan ${nvidiagauge [height][,width] fanlevel [target_id]}
* TEMP ${nvidiagauge [height][,width] gputemp [gpu_id]} * TEMP ${nvidiagauge [height][,width] gputemp [target_id]}
* *
* --==| NVIDIA Graph |==-- (gpu_id is not optional in this case) * --==| NVIDIA Graph |==-- (target_id is not optional in this case)
* LOAD ${nvidiagraph gpuutil [height][,width] [gradient color 1] [gradient * LOAD ${nvidiagraph gpuutil [height][,width] [gradient color 1] [gradient
* color 2] [scale] [-t] [-l] gpu_id} VRAM ${nvidiagraph memutil * color 2] [scale] [-t] [-l] target_id} VRAM ${nvidiagraph memutil
* [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l] * [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l]
* gpu_id} RAM ${nvidiagraph membwutil [height][,width] [gradient color 1] * target_id} RAM ${nvidiagraph membwutil [height][,width] [gradient color 1]
* [gradient color 2] [scale] [-t] [-l] gpu_id} VIDEO ${nvidiagraph videoutil * [gradient color 2] [scale] [-t] [-l] target_id} VIDEO ${nvidiagraph videoutil
* [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l] * [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l]
* gpu_id} PCIe ${nvidiagraph pcieutil [height][,width] [gradient color 1] * target_id} PCIe ${nvidiagraph pcieutil [height][,width] [gradient color 1]
* [gradient color 2] [scale] [-t] [-l] gpu_id} Fan ${nvidiagraph fanlevel * [gradient color 2] [scale] [-t] [-l] target_id} Fan ${nvidiagraph fanlevel
* [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l] * [height][,width] [gradient color 1] [gradient color 2] [scale] [-t] [-l]
* gpu_id} TEMP ${nvidiagraph gputemp [height][,width] [gradient color 1] * target_id} TEMP ${nvidiagraph gputemp [height][,width] [gradient color 1]
* [gradient color 2] [scale] [-t] [-l] gpu_id} * [gradient color 2] [scale] [-t] [-l] target_id}
*/ */
#include "nvidia.h" #include "nvidia.h"
@ -325,7 +325,7 @@ class nvidia_s {
attribute(ATTR_GPU_TEMP), attribute(ATTR_GPU_TEMP),
token(0), token(0),
search(SEARCH_FIRST), search(SEARCH_FIRST),
gpu_id(0) {} target_id(0) {}
const char *command; const char *command;
const char *arg; const char *arg;
QUERY_ID query; QUERY_ID query;
@ -334,7 +334,7 @@ class nvidia_s {
char *token; char *token;
SEARCH_ID search; SEARCH_ID search;
// added new field for GPU id // added new field for GPU id
int gpu_id; int target_id;
}; };
// Cache by value // Cache by value
@ -420,12 +420,12 @@ int set_nvidia_query(struct text_object *obj, const char *arg,
// Added new parameter parsing GPU_ID as 0,1,2,.. // Added new parameter parsing GPU_ID as 0,1,2,..
// if no GPU_ID parameter then default to 0 // if no GPU_ID parameter then default to 0
nvs->gpu_id = 0; nvs->target_id = 0;
char *strbuf = strdup(arg); char *strbuf = strdup(arg);
char *p = strrchr(strbuf, ' '); char *p = strrchr(strbuf, ' ');
if (p && *(p + 1)) { if (p && *(p + 1)) {
nvs->gpu_id = atoi(p + 1); nvs->target_id = atoi(p + 1);
if ((nvs->gpu_id > 0) || !strcmp(p + 1, "0")) { if ((nvs->target_id > 0) || !strcmp(p + 1, "0")) {
ilen = strlen(strbuf); ilen = strlen(strbuf);
ilen = ilen - strlen(p); ilen = ilen - strlen(p);
strbuf[ilen] = 0; strbuf[ilen] = 0;
@ -434,7 +434,7 @@ int set_nvidia_query(struct text_object *obj, const char *arg,
} }
// If the value is negative it is set to 0 // If the value is negative it is set to 0
if (nvs->gpu_id < 0) nvs->gpu_id = 0; if (nvs->target_id < 0) nvs->target_id = 0;
// Extract arguments for nvidiabar, etc, and run set_nvidia_query // Extract arguments for nvidiabar, etc, and run set_nvidia_query
switch (special_type) { switch (special_type) {
@ -908,6 +908,24 @@ static int get_nvidia_string_value(TARGET_ID tid, ATTR_ID aid, char *token,
return value; return value;
} }
bool validate_target_id(Display* dpy, int target_id, ATTR_ID attribute) {
// num_GPU and num_COOLER calculated only once based on the physical target
static int num_GPU = get_nvidia_target_count(dpy, TARGET_GPU) - 1;
static int num_COOLER = get_nvidia_target_count(dpy, TARGET_COOLER) - 1;
if (target_id < 0) return false;
switch (attribute) {
case ATTR_FAN_LEVEL:
case ATTR_FAN_SPEED:
if (target_id > num_COOLER) return false;
break;
default:
if (target_id > num_GPU) return false;
break;
}
return true;
}
// Perform query and print result // Perform query and print result
void print_nvidia_value(struct text_object *obj, char *p, void print_nvidia_value(struct text_object *obj, char *p,
unsigned int p_max_size) { unsigned int p_max_size) {
@ -932,49 +950,30 @@ void print_nvidia_value(struct text_object *obj, char *p,
return; return;
} }
// num_GPU calculated only once based on the physical target
static int num_GPU = get_nvidia_target_count(dpy, TARGET_GPU) - 1;
static int num_COOLER = get_nvidia_target_count(dpy, TARGET_COOLER);
// Assume failure // Assume failure
value = -1; value = -1;
str = nullptr; str = nullptr;
// Perform query // Perform query if the query exists and isnt stupid
if (nvs != nullptr) { if (nvs != nullptr && validate_target_id(dpy, nvs->target_id, nvs->attribute)) {
// Reduce overcommitted GPU number to last GPU
if (nvs->gpu_id > num_GPU) nvs->gpu_id = num_GPU;
// Execute switch by query type // Execute switch by query type
switch (nvs->query) { switch (nvs->query) {
case QUERY_VALUE: case QUERY_VALUE:
switch (nvs->attribute) { value = get_nvidia_value(nvs->target, nvs->attribute, nvs->target_id,
case ATTR_FAN_LEVEL:
/* falls through */
case ATTR_FAN_SPEED:
if (num_COOLER < 1) {
value = -1;
break;
}
/* falls through */
default:
value = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id,
nvs->arg); nvs->arg);
break; break;
}
break;
case QUERY_STRING: case QUERY_STRING:
str = get_nvidia_string(nvs->target, nvs->attribute, nvs->gpu_id, str = get_nvidia_string(nvs->target, nvs->attribute, nvs->target_id,
nvs->arg); nvs->arg);
break; break;
case QUERY_STRING_VALUE: case QUERY_STRING_VALUE:
value = get_nvidia_string_value(nvs->target, nvs->attribute, nvs->token, value = get_nvidia_string_value(nvs->target, nvs->attribute, nvs->token,
nvs->search, nvs->gpu_id, nvs->arg); nvs->search, nvs->target_id, nvs->arg);
break; break;
case QUERY_SPECIAL: case QUERY_SPECIAL:
switch (nvs->attribute) { switch (nvs->attribute) {
case ATTR_PERF_MODE: case ATTR_PERF_MODE:
temp1 = get_nvidia_value(nvs->target, nvs->attribute, nvs->gpu_id, temp1 = get_nvidia_value(nvs->target, nvs->attribute, nvs->target_id,
nvs->arg); nvs->arg);
switch (temp1) { switch (temp1) {
case NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE: case NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE:
@ -996,16 +995,16 @@ void print_nvidia_value(struct text_object *obj, char *p,
if (result < 0) { str = nullptr; } if (result < 0) { str = nullptr; }
break; break;
case ATTR_MEM_FREE: case ATTR_MEM_FREE:
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->target_id,
nvs->arg); nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id, temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->target_id,
nvs->arg); nvs->arg);
value = temp2 - temp1; value = temp2 - temp1;
break; break;
case ATTR_MEM_UTIL: case ATTR_MEM_UTIL:
temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, temp1 = get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->target_id,
nvs->arg); nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id, temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->target_id,
nvs->arg); nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
@ -1034,32 +1033,46 @@ double get_nvidia_barval(struct text_object *obj) {
int temp1; int temp1;
int temp2; int temp2;
double value; double value;
int event_base;
int error_base;
Display *dpy = nvdisplay ? nvdisplay : display;
if (!dpy) {
NORM_ERR("%s: no display set (try setting nvidia_display)", __func__);
return 0;
}
if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base)) {
NORM_ERR("%s: NV-CONTROL X extension not present", __func__);
return 0;
}
// Assume failure // Assume failure
value = 0; value = 0;
// Convert query_result to a percentage using ((val-min)÷(max-min)×100)+0.5 if // Convert query_result to a percentage using ((val-min)÷(max-min)×100)+0.5 if
// needed. // needed.
if (nvs != nullptr) { if (nvs != nullptr && validate_target_id(dpy, nvs->target_id, nvs->attribute)) {
switch (nvs->attribute) { switch (nvs->attribute) {
case ATTR_UTILS_STRING: // one of the percentage utils (gpuutil, case ATTR_UTILS_STRING: // one of the percentage utils (gpuutil,
// membwutil, videoutil and pcieutil) // membwutil, videoutil and pcieutil)
value = value =
get_nvidia_string_value(nvs->target, ATTR_UTILS_STRING, nvs->token, get_nvidia_string_value(nvs->target, ATTR_UTILS_STRING, nvs->token,
nvs->search, nvs->gpu_id, nvs->arg); nvs->search, nvs->target_id, nvs->arg);
break; break;
case ATTR_MEM_UTIL: // memutil case ATTR_MEM_UTIL: // memutil
case ATTR_MEM_USED: case ATTR_MEM_USED:
temp1 = temp1 =
get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, nvs->arg); get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->target_id, nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id, temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->target_id,
nvs->arg); nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_MEM_FREE: // memfree case ATTR_MEM_FREE: // memfree
temp1 = temp1 =
get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->gpu_id, nvs->arg); get_nvidia_value(nvs->target, ATTR_MEM_USED, nvs->target_id, nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->gpu_id, temp2 = get_nvidia_value(nvs->target, ATTR_MEM_TOTAL, nvs->target_id,
nvs->arg); nvs->arg);
value = temp2 - temp1; value = temp2 - temp1;
break; break;
@ -1069,38 +1082,38 @@ double get_nvidia_barval(struct text_object *obj) {
nvs->command, nvs->arg); nvs->command, nvs->arg);
/* falls through */ /* falls through */
case ATTR_FAN_LEVEL: // fanlevel case ATTR_FAN_LEVEL: // fanlevel
value = get_nvidia_value(nvs->target, ATTR_FAN_LEVEL, nvs->gpu_id, value = get_nvidia_value(nvs->target, ATTR_FAN_LEVEL, nvs->target_id,
nvs->arg); nvs->arg);
break; break;
case ATTR_GPU_TEMP: // gputemp (calculate out of gputempthreshold) case ATTR_GPU_TEMP: // gputemp (calculate out of gputempthreshold)
temp1 = temp1 =
get_nvidia_value(nvs->target, ATTR_GPU_TEMP, nvs->gpu_id, nvs->arg); get_nvidia_value(nvs->target, ATTR_GPU_TEMP, nvs->target_id, nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD, temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD,
nvs->gpu_id, nvs->arg); nvs->target_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_AMBIENT_TEMP: // ambienttemp (calculate out of gputempthreshold case ATTR_AMBIENT_TEMP: // ambienttemp (calculate out of gputempthreshold
// for consistency) // for consistency)
temp1 = get_nvidia_value(nvs->target, ATTR_AMBIENT_TEMP, nvs->gpu_id, temp1 = get_nvidia_value(nvs->target, ATTR_AMBIENT_TEMP, nvs->target_id,
nvs->arg); nvs->arg);
temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD, temp2 = get_nvidia_value(nvs->target, ATTR_GPU_TEMP_THRESHOLD,
nvs->gpu_id, nvs->arg); nvs->target_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_GPU_FREQ: // gpufreq (calculate out of gpufreqmax) case ATTR_GPU_FREQ: // gpufreq (calculate out of gpufreqmax)
temp1 = temp1 =
get_nvidia_value(nvs->target, ATTR_GPU_FREQ, nvs->gpu_id, nvs->arg); get_nvidia_value(nvs->target, ATTR_GPU_FREQ, nvs->target_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"nvclockmax", SEARCH_MAX, (char *)"nvclockmax", SEARCH_MAX,
nvs->gpu_id, nvs->arg); nvs->target_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_MEM_FREQ: // memfreq (calculate out of memfreqmax) case ATTR_MEM_FREQ: // memfreq (calculate out of memfreqmax)
temp1 = temp1 =
get_nvidia_value(nvs->target, ATTR_MEM_FREQ, nvs->gpu_id, nvs->arg); get_nvidia_value(nvs->target, ATTR_MEM_FREQ, nvs->target_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"memclockmax", SEARCH_MAX, (char *)"memclockmax", SEARCH_MAX,
nvs->gpu_id, nvs->arg); nvs->target_id, nvs->arg);
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_FREQS_STRING: // mtrfreq (calculate out of memfreqmax) case ATTR_FREQS_STRING: // mtrfreq (calculate out of memfreqmax)
@ -1114,15 +1127,15 @@ double get_nvidia_barval(struct text_object *obj) {
} }
temp1 = temp1 =
get_nvidia_string_value(nvs->target, ATTR_FREQS_STRING, nvs->token, get_nvidia_string_value(nvs->target, ATTR_FREQS_STRING, nvs->token,
SEARCH_MAX, nvs->gpu_id, nvs->arg); SEARCH_MAX, nvs->target_id, nvs->arg);
temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING, temp2 = get_nvidia_string_value(nvs->target, ATTR_PERFMODES_STRING,
(char *)"memTransferRatemax", (char *)"memTransferRatemax",
SEARCH_MAX, nvs->gpu_id, nvs->arg); SEARCH_MAX, nvs->target_id, nvs->arg);
if (temp2 > temp1) temp1 = temp2; // extra safe here if (temp2 > temp1) temp1 = temp2; // extra safe here
value = ((float)temp1 * 100 / (float)temp2) + 0.5; value = ((float)temp1 * 100 / (float)temp2) + 0.5;
break; break;
case ATTR_IMAGE_QUALITY: // imagequality case ATTR_IMAGE_QUALITY: // imagequality
value = get_nvidia_value(nvs->target, ATTR_IMAGE_QUALITY, nvs->gpu_id, value = get_nvidia_value(nvs->target, ATTR_IMAGE_QUALITY, nvs->target_id,
nvs->arg); nvs->arg);
break; break;