summaryrefslogtreecommitdiff
path: root/src/libXNVCtrlAttributes
diff options
context:
space:
mode:
Diffstat (limited to 'src/libXNVCtrlAttributes')
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.c93
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.h12
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c16
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c816
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h23
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c46
6 files changed, 760 insertions, 246 deletions
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
index 73b8f41..661f77c 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
@@ -596,6 +596,7 @@ ReturnStatus NvCtrlQueryTargetCount(const CtrlTarget *ctrl_target,
int *val)
{
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlMissingExtension;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -606,9 +607,9 @@ ReturnStatus NvCtrlQueryTargetCount(const CtrlTarget *ctrl_target,
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret = NvCtrlNvmlQueryTargetCount(ctrl_target,
- target_type,
- val);
+ ret = NvCtrlNvmlQueryTargetCount(ctrl_target,
+ target_type,
+ val);
if ((ret != NvCtrlMissingExtension) &&
(ret != NvCtrlBadHandle) &&
(ret != NvCtrlNotSupported)) {
@@ -621,6 +622,13 @@ ReturnStatus NvCtrlQueryTargetCount(const CtrlTarget *ctrl_target,
case FRAMELOCK_TARGET:
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
case MUX_TARGET:
+ if (!h->nv) {
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
+ }
return NvCtrlNvControlQueryTargetCount(h, target_type, val);
default:
return NvCtrlBadHandle;
@@ -674,6 +682,7 @@ ReturnStatus NvCtrlGetAttributePerms(const CtrlTarget *ctrl_target,
CtrlAttributePerms *perms)
{
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlError;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -688,6 +697,12 @@ ReturnStatus NvCtrlGetAttributePerms(const CtrlTarget *ctrl_target,
case CTRL_ATTRIBUTE_TYPE_STRING:
case CTRL_ATTRIBUTE_TYPE_BINARY_DATA:
case CTRL_ATTRIBUTE_TYPE_STRING_OPERATION:
+
+ ret = NvCtrlNvmlGetAttributePerms(h, attr_type, attr, perms);
+
+ if (ret == NvCtrlSuccess || h->dpy == NULL) {
+ return ret;
+ }
return NvCtrlNvControlGetAttributePerms(h, attr_type, attr, perms);
case CTRL_ATTRIBUTE_TYPE_COLOR:
@@ -760,18 +775,17 @@ ReturnStatus NvCtrlGetDisplayAttribute64(const CtrlTarget *ctrl_target,
if (((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) ||
((attr >= NV_CTRL_ATTR_NV_BASE) &&
(attr <= NV_CTRL_ATTR_NV_LAST_ATTRIBUTE))) {
+ ReturnStatus ret = NvCtrlMissingExtension;
switch (h->target_type) {
case GPU_TARGET:
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret = NvCtrlNvmlGetAttribute(ctrl_target,
- attr,
- val);
- if ((ret != NvCtrlMissingExtension) &&
- (ret != NvCtrlBadHandle) &&
- (ret != NvCtrlNotSupported)) {
+ ret = NvCtrlNvmlGetAttribute(ctrl_target,
+ attr,
+ val);
+ if (ret == NvCtrlSuccess) {
return ret;
}
}
@@ -781,7 +795,13 @@ ReturnStatus NvCtrlGetDisplayAttribute64(const CtrlTarget *ctrl_target,
case FRAMELOCK_TARGET:
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
case MUX_TARGET:
- if (!h->nv) return NvCtrlMissingExtension;
+ if (!h->nv) {
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
+ }
return NvCtrlNvControlGetAttribute(h, display_mask, attr, val);
default:
return NvCtrlBadHandle;
@@ -815,6 +835,7 @@ ReturnStatus NvCtrlSetDisplayAttribute(CtrlTarget *ctrl_target,
int attr, int val)
{
NvCtrlAttributePrivateHandle *h = getPrivateHandle(ctrl_target);
+ ReturnStatus ret = NvCtrlMissingExtension;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -826,7 +847,6 @@ ReturnStatus NvCtrlSetDisplayAttribute(CtrlTarget *ctrl_target,
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret;
ret = NvCtrlNvmlSetAttribute(ctrl_target,
attr,
display_mask,
@@ -844,7 +864,11 @@ ReturnStatus NvCtrlSetDisplayAttribute(CtrlTarget *ctrl_target,
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
case MUX_TARGET:
if (!h->nv) {
- return NvCtrlMissingExtension;
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
}
return NvCtrlNvControlSetAttribute(h, display_mask, attr, val);
default:
@@ -891,6 +915,7 @@ NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target,
CtrlAttributeValidValues *val)
{
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlMissingExtension;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -902,13 +927,10 @@ NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target,
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret;
ret = NvCtrlNvmlGetValidAttributeValues(ctrl_target,
attr,
val);
- if ((ret != NvCtrlMissingExtension) &&
- (ret != NvCtrlBadHandle) &&
- (ret != NvCtrlNotSupported)) {
+ if (ret == NvCtrlSuccess) {
return ret;
}
}
@@ -919,7 +941,11 @@ NvCtrlGetValidDisplayAttributeValues(const CtrlTarget *ctrl_target,
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
case MUX_TARGET:
if (!h->nv) {
- return NvCtrlMissingExtension;
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
}
return NvCtrlNvControlGetValidAttributeValues(h, display_mask,
attr, val);
@@ -965,6 +991,7 @@ NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target,
CtrlAttributeValidValues *val)
{
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlMissingExtension;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -976,13 +1003,10 @@ NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target,
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret;
ret = NvCtrlNvmlGetValidStringAttributeValues(ctrl_target,
attr,
val);
- if ((ret != NvCtrlMissingExtension) &&
- (ret != NvCtrlBadHandle) &&
- (ret != NvCtrlNotSupported)) {
+ if (ret == NvCtrlSuccess) {
return ret;
}
}
@@ -993,7 +1017,11 @@ NvCtrlGetValidStringDisplayAttributeValues(const CtrlTarget *ctrl_target,
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
case MUX_TARGET:
if (!h->nv) {
- return NvCtrlMissingExtension;
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
}
return NvCtrlNvControlGetValidStringDisplayAttributeValues(
h, display_mask, attr, val);
@@ -1174,6 +1202,7 @@ ReturnStatus NvCtrlGetBinaryAttribute(const CtrlTarget *ctrl_target,
unsigned char **data, int *len)
{
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlMissingExtension;
if (h == NULL) {
return NvCtrlBadHandle;
@@ -1184,10 +1213,10 @@ ReturnStatus NvCtrlGetBinaryAttribute(const CtrlTarget *ctrl_target,
case THERMAL_SENSOR_TARGET:
case COOLER_TARGET:
{
- ReturnStatus ret = NvCtrlNvmlGetBinaryAttribute(ctrl_target,
- attr,
- data,
- len);
+ ret = NvCtrlNvmlGetBinaryAttribute(ctrl_target,
+ attr,
+ data,
+ len);
if ((ret != NvCtrlMissingExtension) &&
(ret != NvCtrlBadHandle) &&
(ret != NvCtrlNotSupported)) {
@@ -1199,6 +1228,13 @@ ReturnStatus NvCtrlGetBinaryAttribute(const CtrlTarget *ctrl_target,
case X_SCREEN_TARGET:
case FRAMELOCK_TARGET:
case NVIDIA_3D_VISION_PRO_TRANSCEIVER_TARGET:
+ if (!h->nv) {
+ /*
+ * If there is no connection to the X Driver, return the
+ * non-success value from the NVML query, if available.
+ */
+ return ret;
+ }
return NvCtrlNvControlGetBinaryAttribute(h, display_mask, attr, data, len);
default:
return NvCtrlBadHandle;
@@ -1637,6 +1673,11 @@ NvCtrlEventHandle *NvCtrlGetEventHandle(const CtrlTarget *ctrl_target)
return NULL;
}
+ if (!h->dpy && !h->nv && h->nvml) {
+ /* We are running with NVML lib only. Events not yet supported.*/
+ return NULL;
+ }
+
/* Look for the event handle */
evt_h = NULL;
for (evt_hnode = __event_handles;
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index f6f1f39..20b0dde 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -139,6 +139,7 @@ struct _CtrlSystem {
char *display; /* string for XOpenDisplay */
Display *dpy; /* X display connection */
Bool has_nv_control;
+ Bool has_nvml;
CtrlTargetNode *targets[MAX_TARGET_TYPES]; /* Shadows targetTypeTable */
CtrlTargetNode *physical_screens;
@@ -574,6 +575,17 @@ typedef struct {
#define NV_CTRL_STRING_XV_LAST_ATTRIBUTE (NV_CTRL_STRING_XV_VERSION)
+/*
+ * Additional XVideo string attributes for NvCtrlGetStringDisplayAttribute();
+ */
+
+#define NV_CTRL_STRING_NVML_BASE (NV_CTRL_STRING_XV_LAST_ATTRIBUTE + 1)
+
+#define NV_CTRL_STRING_NVML_VERSION (NV_CTRL_STRING_NVML_BASE)
+
+#define NV_CTRL_STRING_NVML_LAST_ATTRIBUTE (NV_CTRL_STRING_NVML_VERSION)
+
+
#define NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM 0x1
#define NV_CTRL_ATTRIBUTES_XF86VIDMODE_SUBSYSTEM 0x2
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
index 4f5bce9..6cd46c2 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
@@ -41,7 +41,12 @@ NvCtrlInitNvControlAttributes (NvCtrlAttributePrivateHandle *h)
NvCtrlNvControlAttributes *nv;
int ret, major, minor, event, error;
const CtrlTargetTypeInfo *targetTypeInfo;
-
+
+ if (!h->dpy) {
+ nv_warning_msg("NV-CONTROL Display not found.");
+ return NULL;
+ }
+
ret = XNVCTRLQueryExtension (h->dpy, &event, &error);
if (ret != True) {
nv_warning_msg("NV-CONTROL extension not found on this Display.");
@@ -160,6 +165,11 @@ NvCtrlNvControlQueryTargetCount(const NvCtrlAttributePrivateHandle *h,
return NvCtrlBadArgument;
}
+ if (!h->dpy) {
+ nv_warning_msg("NV-CONTROL Display not found.");
+ return NvCtrlError;
+ }
+
ret = XNVCTRLQueryTargetCount(h->dpy, targetTypeInfo->nvctrl, val);
return (ret) ? NvCtrlSuccess : NvCtrlError;
@@ -174,6 +184,10 @@ ReturnStatus NvCtrlNvControlGetAttribute(const NvCtrlAttributePrivateHandle *h,
int value_32;
int major, minor;
+ if (!h->nv) {
+ return NvCtrlMissingExtension;
+ }
+
major = h->nv->major_version;
minor = h->nv->minor_version;
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
index d39f635..7cec7c8 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvml.c
@@ -192,14 +192,29 @@ static Bool LoadNvml(NvCtrlNvmlAttributes *nvml)
GET_SYMBOL_REQUIRED(deviceGetUUID, "nvmlDeviceGetUUID");
GET_SYMBOL_REQUIRED(deviceGetCount, "nvmlDeviceGetCount");
GET_SYMBOL_REQUIRED(deviceGetTemperature, "nvmlDeviceGetTemperature");
- GET_SYMBOL_REQUIRED(deviceGetFanSpeed, "nvmlDeviceGetFanSpeed");
GET_SYMBOL_REQUIRED(deviceGetName, "nvmlDeviceGetName");
GET_SYMBOL_REQUIRED(deviceGetVbiosVersion, "nvmlDeviceGetVbiosVersion");
GET_SYMBOL_REQUIRED(deviceGetMemoryInfo, "nvmlDeviceGetMemoryInfo");
GET_SYMBOL_REQUIRED(deviceGetPciInfo, "nvmlDeviceGetPciInfo");
+ GET_SYMBOL_REQUIRED(deviceGetCurrPcieLinkWidth, "nvmlDeviceGetCurrPcieLinkWidth");
GET_SYMBOL_REQUIRED(deviceGetMaxPcieLinkGeneration, "nvmlDeviceGetMaxPcieLinkGeneration");
GET_SYMBOL_REQUIRED(deviceGetMaxPcieLinkWidth, "nvmlDeviceGetMaxPcieLinkWidth");
GET_SYMBOL_REQUIRED(deviceGetVirtualizationMode, "nvmlDeviceGetVirtualizationMode");
+ GET_SYMBOL_REQUIRED(deviceGetUtilizationRates, "nvmlDeviceGetUtilizationRates");
+ GET_SYMBOL_REQUIRED(deviceGetTemperatureThreshold, "nvmlDeviceGetTemperatureThreshold");
+ GET_SYMBOL_REQUIRED(deviceGetFanSpeed_v2, "nvmlDeviceGetFanSpeed_v2");
+ GET_SYMBOL_REQUIRED(systemGetDriverVersion, "nvmlSystemGetDriverVersion");
+ GET_SYMBOL_REQUIRED(deviceGetEccMode, "nvmlDeviceGetEccMode");
+ GET_SYMBOL_REQUIRED(deviceSetEccMode, "nvmlDeviceSetEccMode");
+ GET_SYMBOL_REQUIRED(deviceGetTotalEccErrors, "nvmlDeviceGetTotalEccErrors");
+ GET_SYMBOL_REQUIRED(deviceClearEccErrorCounts, "nvmlDeviceClearEccErrorCounts");
+ GET_SYMBOL_REQUIRED(systemGetNVMLVersion, "nvmlSystemGetNVMLVersion");
+ GET_SYMBOL_REQUIRED(deviceGetMemoryErrorCounter, "nvmlDeviceGetMemoryErrorCounter");
+ GET_SYMBOL_REQUIRED(deviceGetNumGpuCores, "nvmlDeviceGetNumGpuCores");
+ GET_SYMBOL_REQUIRED(deviceGetMemoryBusWidth, "nvmlDeviceGetMemoryBusWidth");
+ GET_SYMBOL_REQUIRED(deviceGetIrqNum, "nvmlDeviceGetIrqNum");
+ GET_SYMBOL_REQUIRED(deviceGetPowerSource, "nvmlDeviceGetPowerSource");
+ GET_SYMBOL_REQUIRED(deviceGetNumFans, "nvmlDeviceGetNumFans");
#undef GET_SYMBOL_REQUIRED
/* Do not fail with older drivers */
@@ -207,6 +222,7 @@ static Bool LoadNvml(NvCtrlNvmlAttributes *nvml)
nvml->lib._proc = dlsym(nvml->lib.handle, _name);
GET_SYMBOL_OPTIONAL(deviceGetGridLicensableFeatures, "nvmlDeviceGetGridLicensableFeatures_v4");
+ GET_SYMBOL_OPTIONAL(deviceGetMemoryInfo_v2, "nvmlDeviceGetMemoryInfo_v2");
#undef GET_SYMBOL_OPTIONAL
ret = nvml->lib.init();
@@ -243,8 +259,8 @@ static Bool matchNvCtrlWithNvmlIds(const NvCtrlNvmlAttributes *nvml,
int nvctrlGpuCount = 0;
/* Get the gpu count returned by NV-CONTROL. */
- if (!XNVCTRLQueryTargetCount(h->dpy, NV_CTRL_TARGET_TYPE_GPU,
- &nvctrlGpuCount)) {
+ if (h->nv && !XNVCTRLQueryTargetCount(h->dpy, NV_CTRL_TARGET_TYPE_GPU,
+ &nvctrlGpuCount)) {
return FALSE;
}
@@ -367,7 +383,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
nvmlReturn_t ret = nvml->lib.deviceGetHandleByIndex(devIdx, &device);
if (ret == NVML_SUCCESS) {
unsigned int temp;
- unsigned int speed;
+ unsigned int fans;
/*
* XXX Currently, NVML only allows to get the GPU temperature so
@@ -387,12 +403,7 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
nvml->sensorCount++;
}
- /*
- * XXX NVML assumes at most 1 fan per GPU so check for
- * nvmlDeviceGetFanSpeed success to figure out if that fan is
- * available.
- */
- ret = nvml->lib.deviceGetFanSpeed(device, &speed);
+ ret = nvml->lib.deviceGetNumFans(device, &fans);
if (ret == NVML_SUCCESS) {
if ((h->target_type == COOLER_TARGET) &&
(h->target_id == nvml->coolerCount)) {
@@ -400,21 +411,20 @@ NvCtrlNvmlAttributes *NvCtrlInitNvmlAttributes(NvCtrlAttributePrivateHandle *h)
nvml->deviceIdx = devIdx;
}
- nvml->coolerCountPerGPU[i] = 1;
- nvml->coolerCount++;
+ nvml->coolerCountPerGPU[i] = fans;
+ nvml->coolerCount += fans;
}
}
}
/*
- * NVML doesn't have support to handle more than 1 fan per GPU. Make sure
- * total number of cooler probed by NVML are same as that of reported by
- * NV-CONTROL, otherwise do not initialize NVML sub-system.
+ * Consistency check between X/NV-CONTROL and NVML.
*/
- if (!XNVCTRLQueryTargetCount(h->dpy, NV_CTRL_TARGET_TYPE_COOLER,
- &nvctrlCoolerCount) ||
- (nvctrlCoolerCount != nvml->coolerCount)) {
- goto fail;
+ if (h->nv &&
+ (!XNVCTRLQueryTargetCount(h->dpy, NV_CTRL_TARGET_TYPE_COOLER,
+ &nvctrlCoolerCount) ||
+ (nvctrlCoolerCount != nvml->coolerCount))) {
+ nv_warning_msg("Inconsistent number of fans detected.");
}
nvfree(nvctrlToNvmlId);
@@ -495,10 +505,50 @@ ReturnStatus NvCtrlNvmlQueryTargetCount(const CtrlTarget *ctrl_target,
/*
- * Get NVML String Attribute Values
+ * Get NVML String Attribute Values that do not require a control target.
*/
-#ifdef NVML_EXPERIMENTAL
+static ReturnStatus NvCtrlNvmlGetGeneralStringAttribute(const CtrlTarget *ctrl_target,
+ int attr, char **ptr)
+{
+ char res[MAX_NVML_STR_LEN];
+ const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ nvmlReturn_t ret;
+ *ptr = NULL;
+
+ if ((h == NULL) || (h->nvml == NULL)) {
+ return NvCtrlBadHandle;
+ }
+
+ switch (attr) {
+ case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
+ ret = h->nvml->lib.systemGetDriverVersion(res, MAX_NVML_STR_LEN);
+ break;
+
+ case NV_CTRL_STRING_NVML_VERSION:
+ ret = h->nvml->lib.systemGetNVMLVersion(res, MAX_NVML_STR_LEN);
+ break;
+
+ default:
+ /* This is expected to fall through silently. */
+ return NvCtrlNotSupported;
+ }
+
+ if (ret == NVML_SUCCESS) {
+ *ptr = strdup(res);
+ return NvCtrlSuccess;
+ }
+
+ /* An NVML error occurred */
+ printNvmlError(ret);
+ return NvCtrlNotSupported;
+}
+
+
+
+/*
+ * Get NVML String Attribute Values
+ */
static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_target,
int attr, char **ptr)
@@ -531,11 +581,33 @@ static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_targe
ret = nvml->lib.deviceGetUUID(device, res, MAX_NVML_STR_LEN);
break;
- case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
+ case NV_CTRL_STRING_GPU_UTILIZATION:
+ {
+ nvmlUtilization_t util;
+
+ if (ctrl_target->system->has_nv_control) {
+ /*
+ * Not all utilization types are currently available via
+ * NVML so, if accessible, get the rates from X.
+ */
+ return NvCtrlNotSupported;
+ }
+
+ ret = nvml->lib.deviceGetUtilizationRates(device, &util);
+
+ if (ret != NVML_SUCCESS) {
+ break;
+ }
+
+ snprintf(res, sizeof(res),
+ "graphics=%d, memory=%d",
+ util.gpu, util.memory);
+
+ break;
+ }
case NV_CTRL_STRING_SLI_MODE:
case NV_CTRL_STRING_PERFORMANCE_MODES:
case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS:
- case NV_CTRL_STRING_GPU_UTILIZATION:
case NV_CTRL_STRING_MULTIGPU_MODE:
/*
* XXX We'll eventually need to add support for this attributes
@@ -562,22 +634,26 @@ static ReturnStatus NvCtrlNvmlGetGPUStringAttribute(const CtrlTarget *ctrl_targe
return NvCtrlNotSupported;
}
-#endif // NVML_EXPERIMENTAL
+
ReturnStatus NvCtrlNvmlGetStringAttribute(const CtrlTarget *ctrl_target,
int attr, char **ptr)
{
+ ReturnStatus ret;
+
if (NvmlMissing(ctrl_target)) {
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
/*
- * This shouldn't be reached for target types that are not handled through
- * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
- * to date).
+ * Check for attributes that don't require a target, else continue to
+ * supported target types.
*/
- assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target)));
+ ret = NvCtrlNvmlGetGeneralStringAttribute(ctrl_target, attr, ptr);
+
+ if (ret == NvCtrlSuccess) {
+ return NvCtrlSuccess;
+ }
switch (NvCtrlGetTargetType(ctrl_target)) {
case GPU_TARGET:
@@ -600,10 +676,6 @@ ReturnStatus NvCtrlNvmlGetStringAttribute(const CtrlTarget *ctrl_target,
default:
return NvCtrlBadHandle;
}
-
-#else
- return NvCtrlNotSupported;
-#endif
}
@@ -612,7 +684,7 @@ ReturnStatus NvCtrlNvmlGetStringAttribute(const CtrlTarget *ctrl_target,
* Set NVML String Attribute Values
*/
-#ifdef NVML_EXPERIMENTAL
+
static ReturnStatus NvCtrlNvmlSetGPUStringAttribute(CtrlTarget *ctrl_target,
int attr, const char *ptr)
@@ -656,7 +728,7 @@ static ReturnStatus NvCtrlNvmlSetGPUStringAttribute(CtrlTarget *ctrl_target,
return NvCtrlNotSupported;
}
-#endif // NVML_EXPERIMENTAL
+
ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target,
int attr, const char *ptr)
@@ -665,7 +737,6 @@ ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target,
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
/*
* This shouldn't be reached for target types that are not handled through
* NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
@@ -695,10 +766,6 @@ ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target,
default:
return NvCtrlBadHandle;
}
-
-#else
- return NvCtrlNotSupported;
-#endif
}
@@ -710,7 +777,7 @@ ReturnStatus NvCtrlNvmlSetStringAttribute(CtrlTarget *ctrl_target,
static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
int attr, int64_t *val)
{
- unsigned int res;
+ unsigned int res = 0;
const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
const NvCtrlNvmlAttributes *nvml;
nvmlDevice_t device;
@@ -725,20 +792,35 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
-#ifdef NVML_EXPERIMENTAL
case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
{
- nvmlMemory_t memory;
- ret = nvml->lib.deviceGetMemoryInfo(device, &memory);
- if (ret == NVML_SUCCESS) {
- switch (attr) {
- case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
- res = memory.total >> 20; // bytes --> MB
- break;
- case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
- res = memory.used >> 20; // bytes --> MB
- break;
+ if (nvml->lib.deviceGetMemoryInfo_v2) {
+ nvmlMemory_v2_t memory;
+ memory.version = nvmlMemory_v2;
+ ret = nvml->lib.deviceGetMemoryInfo_v2(device, &memory);
+ if (ret == NVML_SUCCESS) {
+ switch (attr) {
+ case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
+ res = memory.total >> 20; // bytes --> MB
+ break;
+ case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
+ res = memory.used >> 20; // bytes --> MB
+ break;
+ }
+ }
+ } else {
+ nvmlMemory_t memory;
+ ret = nvml->lib.deviceGetMemoryInfo(device, &memory);
+ if (ret == NVML_SUCCESS) {
+ switch (attr) {
+ case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
+ res = memory.total >> 20; // bytes --> MB
+ break;
+ case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
+ res = memory.used >> 20; // bytes --> MB
+ break;
+ }
}
}
}
@@ -787,41 +869,127 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetMaxPcieLinkGeneration(device, &res);
break;
+ case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH:
+ ret = nvml->lib.deviceGetCurrPcieLinkWidth(device, &res);
+ break;
case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
ret = nvml->lib.deviceGetMaxPcieLinkWidth(device, &res);
break;
-#else
- case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
- case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
- case NV_CTRL_PCI_DOMAIN:
- case NV_CTRL_PCI_BUS:
- case NV_CTRL_PCI_DEVICE:
- case NV_CTRL_PCI_FUNCTION:
- case NV_CTRL_PCI_ID:
- case NV_CTRL_GPU_PCIE_GENERATION:
- case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
-#endif // NVML_EXPERIMENTAL
+ case NV_CTRL_GPU_SLOWDOWN_THRESHOLD:
+ ret = nvml->lib.deviceGetTemperatureThreshold(device,
+ NVML_TEMPERATURE_THRESHOLD_SLOWDOWN ,&res);
+ break;
+ case NV_CTRL_GPU_SHUTDOWN_THRESHOLD:
+ ret = nvml->lib.deviceGetTemperatureThreshold(device,
+ NVML_TEMPERATURE_THRESHOLD_SHUTDOWN ,&res);
+ break;
+ case NV_CTRL_GPU_CORE_TEMPERATURE:
+ ret = nvml->lib.deviceGetTemperature(device,
+ NVML_TEMPERATURE_GPU,
+ &res);
+ break;
+
+ case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
+ case NV_CTRL_GPU_ECC_SUPPORTED:
+ {
+ nvmlEnableState_t current, pending;
+ ret = nvml->lib.deviceGetEccMode(device, &current, &pending);
+ switch (attr) {
+ case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
+ res = (ret == NVML_SUCCESS) ?
+ NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED_TRUE :
+ NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED_FALSE;
+ break;
+ case NV_CTRL_GPU_ECC_SUPPORTED:
+ res = (ret == NVML_SUCCESS) ?
+ NV_CTRL_GPU_ECC_SUPPORTED_TRUE :
+ NV_CTRL_GPU_ECC_SUPPORTED_FALSE;
+ break;
+ }
+ }
+ break;
+
+ case NV_CTRL_GPU_ECC_CONFIGURATION:
+ case NV_CTRL_GPU_ECC_STATUS:
+ {
+ nvmlEnableState_t current, pending;
+ ret = nvml->lib.deviceGetEccMode(device, &current, &pending);
+ if (ret == NVML_SUCCESS) {
+ switch (attr) {
+ case NV_CTRL_GPU_ECC_STATUS:
+ res = current;
+ break;
+ case NV_CTRL_GPU_ECC_CONFIGURATION:
+ res = pending;
+ break;
+ }
+ }
+ }
+ break;
+
+ case NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS:
+ {
+ unsigned long long eccCounts;
+ nvmlEccCounterType_t counterType;
+ nvmlMemoryErrorType_t errorType;
+ switch (attr) {
+ case NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS:
+ errorType = NVML_MEMORY_ERROR_TYPE_CORRECTED;
+ counterType = NVML_VOLATILE_ECC;
+ break;
+ case NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS:
+ errorType = NVML_MEMORY_ERROR_TYPE_CORRECTED;
+ counterType = NVML_AGGREGATE_ECC;
+ break;
+ case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS:
+ errorType = NVML_MEMORY_ERROR_TYPE_UNCORRECTED;
+ counterType = NVML_VOLATILE_ECC;
+ break;
+ case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS:
+ errorType = NVML_MEMORY_ERROR_TYPE_UNCORRECTED;
+ counterType = NVML_AGGREGATE_ECC;
+ break;
+ }
+
+ ret = nvml->lib.deviceGetTotalEccErrors(device, errorType,
+ counterType, &eccCounts);
+ if (ret == NVML_SUCCESS) {
+ if (val) {
+ *val = eccCounts;
+ }
+ return NvCtrlSuccess;
+ }
+ }
+ break;
+
+ case NV_CTRL_GPU_CORES:
+ ret = nvml->lib.deviceGetNumGpuCores(device, &res);
+ break;
+ case NV_CTRL_GPU_MEMORY_BUS_WIDTH:
+ ret = nvml->lib.deviceGetMemoryBusWidth(device, &res);
+ break;
+ case NV_CTRL_IRQ:
+ ret = nvml->lib.deviceGetIrqNum(device, &res);
+ break;
+ case NV_CTRL_GPU_POWER_SOURCE:
+ assert(NV_CTRL_GPU_POWER_SOURCE_AC == NVML_POWER_SOURCE_AC);
+ assert(NV_CTRL_GPU_POWER_SOURCE_BATTERY == NVML_POWER_SOURCE_BATTERY);
+ ret = nvml->lib.deviceGetPowerSource(device, &res);
+ break;
+
+ case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION:
case NV_CTRL_VIDEO_RAM:
- case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH:
case NV_CTRL_GPU_PCIE_MAX_LINK_SPEED:
case NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED:
case NV_CTRL_BUS_TYPE:
- case NV_CTRL_GPU_MEMORY_BUS_WIDTH:
- case NV_CTRL_GPU_CORES:
- case NV_CTRL_IRQ:
case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
- case NV_CTRL_GPU_POWER_SOURCE:
case NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL:
case NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE:
case NV_CTRL_GPU_POWER_MIZER_MODE:
case NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE:
- case NV_CTRL_GPU_ECC_SUPPORTED:
- case NV_CTRL_GPU_ECC_STATUS:
- case NV_CTRL_GPU_ECC_CONFIGURATION:
- case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION:
- case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS:
- case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS:
- case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
case NV_CTRL_ENABLED_DISPLAYS:
case NV_CTRL_CONNECTED_DISPLAYS:
case NV_CTRL_MAX_SCREEN_WIDTH:
@@ -836,10 +1004,8 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
case NV_CTRL_ATTR_NV_MINOR_VERSION:
case NV_CTRL_OPERATING_SYSTEM:
case NV_CTRL_NO_SCANOUT:
- case NV_CTRL_GPU_CORE_TEMPERATURE:
case NV_CTRL_AMBIENT_TEMPERATURE:
case NV_CTRL_GPU_CURRENT_CLOCK_FREQS:
- case NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS:
case NV_CTRL_VIDEO_ENCODER_UTILIZATION:
case NV_CTRL_VIDEO_DECODER_UTILIZATION:
case NV_CTRL_FRAMELOCK:
@@ -886,14 +1052,16 @@ static ReturnStatus NvCtrlNvmlGetGPUAttribute(const CtrlTarget *ctrl_target,
default:
/* Did we forget to handle a GPU integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of GPU "
- "(%d)", INT_ATTRIBUTE_NAME(attr), attr,
- NvCtrlGetTargetId(ctrl_target));
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of GPU "
+ "(%d)", INT_ATTRIBUTE_NAME(attr), attr,
+ NvCtrlGetTargetId(ctrl_target));
return NvCtrlNotSupported;
}
if (ret == NVML_SUCCESS) {
- *val = res;
+ if (val) {
+ *val = res;
+ }
return NvCtrlSuccess;
}
}
@@ -951,7 +1119,7 @@ static ReturnStatus NvCtrlNvmlGetGridLicensableFeatures(const CtrlTarget *ctrl_t
return NvCtrlNotSupported;
}
-#ifdef NVML_EXPERIMENTAL
+
static int getThermalCoolerId(const NvCtrlAttributePrivateHandle *h,
unsigned int thermalCoolerCount,
@@ -1003,11 +1171,7 @@ static ReturnStatus NvCtrlNvmlGetThermalAttribute(const CtrlTarget *ctrl_target,
if (ret == NVML_SUCCESS) {
switch (attr) {
case NV_CTRL_THERMAL_SENSOR_READING:
- ret = nvml->lib.deviceGetTemperature(device,
- NVML_TEMPERATURE_GPU,
- &res);
- break;
-
+
case NV_CTRL_THERMAL_SENSOR_PROVIDER:
case NV_CTRL_THERMAL_SENSOR_TARGET:
/*
@@ -1018,9 +1182,9 @@ static ReturnStatus NvCtrlNvmlGetThermalAttribute(const CtrlTarget *ctrl_target,
default:
/* Did we forget to handle a sensor integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of "
- "Thermal sensor (%d)", INT_ATTRIBUTE_NAME(attr),
- attr, NvCtrlGetTargetId(ctrl_target));
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of "
+ "Thermal sensor (%d)", INT_ATTRIBUTE_NAME(attr),
+ attr, NvCtrlGetTargetId(ctrl_target));
return NvCtrlNotSupported;
}
@@ -1062,10 +1226,11 @@ static ReturnStatus NvCtrlNvmlGetCoolerAttribute(const CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
- case NV_CTRL_THERMAL_COOLER_LEVEL:
- ret = nvml->lib.deviceGetFanSpeed(device, &res);
+ case NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL:
+ ret = nvml->lib.deviceGetFanSpeed_v2(device, coolerId, &res);
break;
+ case NV_CTRL_THERMAL_COOLER_LEVEL:
case NV_CTRL_THERMAL_COOLER_SPEED:
case NV_CTRL_THERMAL_COOLER_CONTROL_TYPE:
case NV_CTRL_THERMAL_COOLER_TARGET:
@@ -1077,9 +1242,9 @@ static ReturnStatus NvCtrlNvmlGetCoolerAttribute(const CtrlTarget *ctrl_target,
default:
/* Did we forget to handle a cooler integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of Fan "
- "(%d)", INT_ATTRIBUTE_NAME(attr), attr,
- NvCtrlGetTargetId(ctrl_target));
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of Fan "
+ "(%d)", INT_ATTRIBUTE_NAME(attr), attr,
+ NvCtrlGetTargetId(ctrl_target));
return NvCtrlNotSupported;
}
@@ -1093,7 +1258,8 @@ static ReturnStatus NvCtrlNvmlGetCoolerAttribute(const CtrlTarget *ctrl_target,
printNvmlError(ret);
return NvCtrlNotSupported;
}
-#endif // NVML_EXPERIMENTAL
+
+
ReturnStatus NvCtrlNvmlGetAttribute(const CtrlTarget *ctrl_target,
int attr, int64_t *val)
@@ -1112,18 +1278,12 @@ ReturnStatus NvCtrlNvmlGetAttribute(const CtrlTarget *ctrl_target,
switch (NvCtrlGetTargetType(ctrl_target)) {
case GPU_TARGET:
return NvCtrlNvmlGetGPUAttribute(ctrl_target, attr, val);
-#ifdef NVML_EXPERIMENTAL
case THERMAL_SENSOR_TARGET:
return NvCtrlNvmlGetThermalAttribute(ctrl_target, attr, val);
case COOLER_TARGET:
return NvCtrlNvmlGetCoolerAttribute(ctrl_target, attr, val);
-#else
- case THERMAL_SENSOR_TARGET:
- case COOLER_TARGET:
- return NvCtrlNotSupported;
-#endif
default:
- return NvCtrlBadHandle;
+ return NvCtrlNotSupported;
}
}
@@ -1155,7 +1315,7 @@ ReturnStatus NvCtrlNvmlGetGridLicenseAttributes(const CtrlTarget *ctrl_target,
* Set NVML Attribute Values
*/
-#ifdef NVML_EXPERIMENTAL
+
static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
int attr, int index, int val)
@@ -1174,9 +1334,28 @@ static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
+ case NV_CTRL_GPU_ECC_CONFIGURATION:
+ ret = nvml->lib.deviceSetEccMode(device, val);
+ break;
+
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS:
+ {
+ nvmlEccCounterType_t counterType = 0;
+ switch (val) {
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS_VOLATILE:
+ counterType = NVML_VOLATILE_ECC;
+ break;
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS_AGGREGATE:
+ counterType = NVML_AGGREGATE_ECC;
+ break;
+ }
+ ret = nvml->lib.deviceClearEccErrorCounts(device,
+ counterType);
+ }
+ break;
+
case NV_CTRL_GPU_CURRENT_CLOCK_FREQS:
case NV_CTRL_GPU_POWER_MIZER_MODE:
- case NV_CTRL_GPU_ECC_CONFIGURATION:
case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
case NV_CTRL_DITHERING:
case NV_CTRL_DITHERING_MODE:
@@ -1193,9 +1372,9 @@ static ReturnStatus NvCtrlNvmlSetGPUAttribute(CtrlTarget *ctrl_target,
default:
/* Did we forget to handle a GPU integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of GPU "
- "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
- attr, NvCtrlGetTargetId(ctrl_target), val);
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of GPU "
+ "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
+ attr, NvCtrlGetTargetId(ctrl_target), val);
return NvCtrlNotSupported;
}
@@ -1244,9 +1423,9 @@ static ReturnStatus NvCtrlNvmlSetCoolerAttribute(CtrlTarget *ctrl_target,
default:
/* Did we forget to handle a cooler integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of Fan "
- "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
- attr, NvCtrlGetTargetId(ctrl_target), val);
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of Fan "
+ "(%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
+ attr, NvCtrlGetTargetId(ctrl_target), val);
return NvCtrlNotSupported;
}
@@ -1260,7 +1439,7 @@ static ReturnStatus NvCtrlNvmlSetCoolerAttribute(CtrlTarget *ctrl_target,
return NvCtrlNotSupported;
}
-#endif // NVML_EXPERIMENTAL
+
ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr,
int index, int val)
@@ -1269,7 +1448,6 @@ ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr,
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
/*
* This shouldn't be reached for target types that are not handled through
* NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
@@ -1283,9 +1461,9 @@ ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr,
case THERMAL_SENSOR_TARGET:
/* Did we forget to handle a sensor integer attribute? */
- nv_warning_msg("Unhandled integer attribute %s (%d) of Thermal "
- "sensor (%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
- attr, NvCtrlGetTargetId(ctrl_target), val);
+ nv_info_msg("", "Unhandled integer attribute %s (%d) of Thermal "
+ "sensor (%d) (set to %d)", INT_ATTRIBUTE_NAME(attr),
+ attr, NvCtrlGetTargetId(ctrl_target), val);
return NvCtrlNotSupported;
case COOLER_TARGET:
@@ -1293,19 +1471,47 @@ ReturnStatus NvCtrlNvmlSetAttribute(CtrlTarget *ctrl_target, int attr,
default:
return NvCtrlBadHandle;
}
-
-#else
- return NvCtrlNotSupported;
-#endif
}
+static nvmlReturn_t getDeviceMemoryCounts(const CtrlTarget *ctrl_target,
+ const NvCtrlNvmlAttributes *nvml,
+ nvmlDevice_t device,
+ nvmlMemoryErrorType_t errorType,
+ nvmlEccCounterType_t counterType,
+ unsigned char **data, int *len)
+{
+ unsigned long long count;
+ int *counts = (int *) nvalloc(sizeof(int) * NVML_MEMORY_LOCATION_COUNT);
+ nvmlReturn_t ret, anySuccess = NVML_ERROR_NOT_SUPPORTED;
+ int i;
+
+ for (i = NVML_MEMORY_LOCATION_L1_CACHE;
+ i < NVML_MEMORY_LOCATION_COUNT;
+ i++) {
+
+ ret = nvml->lib.deviceGetMemoryErrorCounter(device, errorType,
+ counterType, i, &count);
+ if (ret == NVML_SUCCESS) {
+ anySuccess = NVML_SUCCESS;
+ counts[i] = (int) count;
+ } else {
+ counts[i] = -1;
+ }
+ }
+
+ *data = (unsigned char *) counts;
+ *len = sizeof(int) * NVML_MEMORY_LOCATION_COUNT;
+
+ return anySuccess;
+}
+
/*
* Get NVML Binary Attribute Values
*/
-#ifdef NVML_EXPERIMENTAL
+
static ReturnStatus
NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target,
@@ -1325,8 +1531,66 @@ NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
- case NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU:
case NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU:
+ {
+ unsigned int *fan_data;
+ unsigned int count = 0;
+ int offset = 0;
+ int i = 0;
+
+ ret = nvml->lib.deviceGetNumFans(device, &count);
+ if (ret != NVML_SUCCESS) {
+ return NvCtrlNotSupported;
+ }
+
+ /*
+ * The format of the returned data is:
+ *
+ * int unsigned int number of COOLERS
+ * int * n unsigned int COOLER indices
+ */
+
+ *len = (count + 1) * sizeof(unsigned int);
+ fan_data = (unsigned int *) nvalloc(*len);
+ memset(fan_data, 0, *len);
+ *data = (unsigned char *) fan_data;
+
+ /* Calculate global fan index offset for this GPU */
+ for (i = 0; i < nvml->deviceIdx; i++) {
+ offset += nvml->coolerCountPerGPU[i];
+ }
+
+ fan_data[0] = count;
+ for (i = 0; i < count; i++) {
+ fan_data[i+1] = i + offset;
+ }
+ break;
+ }
+ case NV_CTRL_BINARY_DATA_GPU_ECC_DETAILED_ERRORS_SINGLE_BIT:
+ ret = getDeviceMemoryCounts(ctrl_target, nvml, device,
+ NVML_MEMORY_ERROR_TYPE_CORRECTED,
+ NVML_VOLATILE_ECC,
+ data, len);
+ break;
+ case NV_CTRL_BINARY_DATA_GPU_ECC_DETAILED_ERRORS_DOUBLE_BIT:
+ ret = getDeviceMemoryCounts(ctrl_target, nvml, device,
+ NVML_MEMORY_ERROR_TYPE_UNCORRECTED,
+ NVML_VOLATILE_ECC,
+ data, len);
+ break;
+ case NV_CTRL_BINARY_DATA_GPU_ECC_DETAILED_ERRORS_SINGLE_BIT_AGGREGATE:
+ ret = getDeviceMemoryCounts(ctrl_target, nvml, device,
+ NVML_MEMORY_ERROR_TYPE_CORRECTED,
+ NVML_AGGREGATE_ECC,
+ data, len);
+ break;
+ case NV_CTRL_BINARY_DATA_GPU_ECC_DETAILED_ERRORS_DOUBLE_BIT_AGGREGATE:
+ ret = getDeviceMemoryCounts(ctrl_target, nvml, device,
+ NVML_MEMORY_ERROR_TYPE_UNCORRECTED,
+ NVML_AGGREGATE_ECC,
+ data, len);
+ break;
+ case NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU:
case NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU:
case NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU:
case NV_CTRL_BINARY_DATA_DISPLAYS_ON_GPU:
@@ -1356,7 +1620,7 @@ NvCtrlNvmlGetGPUBinaryAttribute(const CtrlTarget *ctrl_target,
return NvCtrlNotSupported;
}
-#endif // NVML_EXPERIMENTAL
+
ReturnStatus
NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target,
@@ -1366,7 +1630,6 @@ NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target,
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
/*
* This shouldn't be reached for target types that are not handled through
* NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
@@ -1398,10 +1661,6 @@ NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target,
default:
return NvCtrlBadHandle;
}
-
-#else
- return NvCtrlNotSupported;
-#endif
}
@@ -1410,28 +1669,31 @@ NvCtrlNvmlGetBinaryAttribute(const CtrlTarget *ctrl_target,
* Get NVML Valid String Attribute Values
*/
-#ifdef NVML_EXPERIMENTAL
+
static ReturnStatus
NvCtrlNvmlGetGPUValidStringAttributeValues(int attr,
CtrlAttributeValidValues *val)
{
switch (attr) {
+ case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
case NV_CTRL_STRING_PRODUCT_NAME:
case NV_CTRL_STRING_VBIOS_VERSION:
- case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
+ case NV_CTRL_STRING_GPU_UUID:
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING;
+ return NvCtrlSuccess;
+
case NV_CTRL_STRING_SLI_MODE:
case NV_CTRL_STRING_PERFORMANCE_MODES:
case NV_CTRL_STRING_MULTIGPU_MODE:
case NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS:
- case NV_CTRL_STRING_GPU_UUID:
case NV_CTRL_STRING_GPU_UTILIZATION:
/*
* XXX We'll eventually need to add support for this attributes. For
* string attributes, NV-CONTROL only sets the attribute type
* and permissions so no actual NVML call will be needed.
*/
- return NvCtrlNotSupported;
+ return NvCtrlAttributeNotAvailable;
default:
/* The attribute queried is not GPU-targeted */
@@ -1441,25 +1703,54 @@ NvCtrlNvmlGetGPUValidStringAttributeValues(int attr,
return NvCtrlSuccess;
}
-#endif // NVML_EXPERIMENTAL
+
+
+static ReturnStatus convertValidTypeToAttributeType(CtrlAttributeValidType val,
+ CtrlAttributeType *type)
+{
+ switch (val) {
+ case CTRL_ATTRIBUTE_VALID_TYPE_INTEGER:
+ case CTRL_ATTRIBUTE_VALID_TYPE_BOOL:
+ case CTRL_ATTRIBUTE_VALID_TYPE_BITMASK:
+ case CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER:
+ *type = CTRL_ATTRIBUTE_TYPE_INTEGER;
+ break;
+ case CTRL_ATTRIBUTE_VALID_TYPE_STRING:
+ *type = CTRL_ATTRIBUTE_TYPE_STRING;
+ break;
+ case CTRL_ATTRIBUTE_VALID_TYPE_STRING_OPERATION:
+ *type = CTRL_ATTRIBUTE_TYPE_STRING_OPERATION;
+ break;
+ case CTRL_ATTRIBUTE_VALID_TYPE_BINARY_DATA:
+ *type = CTRL_ATTRIBUTE_TYPE_BINARY_DATA;
+ break;
+ default:
+ return NvCtrlAttributeNotAvailable;
+ }
+
+ return NvCtrlSuccess;
+}
+
+
ReturnStatus
NvCtrlNvmlGetValidStringAttributeValues(const CtrlTarget *ctrl_target,
int attr,
CtrlAttributeValidValues *val)
{
+ const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlAttributeNotAvailable;
+ CtrlAttributeType attr_type;
+
if (NvmlMissing(ctrl_target)) {
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
- ReturnStatus ret;
- /*
- * This shouldn't be reached for target types that are not handled through
- * NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
- * to date).
- */
- assert(TARGET_TYPE_IS_NVML_COMPATIBLE(NvCtrlGetTargetType(ctrl_target)));
+ if (val) {
+ memset(val, 0, sizeof(*val));
+ } else {
+ return NvCtrlBadArgument;
+ }
switch (NvCtrlGetTargetType(ctrl_target)) {
case GPU_TARGET:
@@ -1477,31 +1768,17 @@ NvCtrlNvmlGetValidStringAttributeValues(const CtrlTarget *ctrl_target,
break;
}
-
- /*
- * XXX Did we forgot to handle this attribute? - REMOVE THIS after
- * nvidia-settings NVML migration work is done
- */
- if (ret == NvCtrlAttributeNotAvailable) {
- const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
- ReturnStatus ret2;
-
- if (!h->nv) {
- return NvCtrlMissingExtension;
- }
-
- ret2 = NvCtrlNvControlGetValidStringDisplayAttributeValues(h, 0, attr, val);
+ if (ret == NvCtrlSuccess) {
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_STRING;
+ }
- assert(ret2 == NvCtrlAttributeNotAvailable);
+ ret = convertValidTypeToAttributeType(val->valid_type, &attr_type);
- return ret2;
+ if (ret != NvCtrlSuccess) {
+ return ret;
}
- return ret;
-
-#else
- return NvCtrlNotSupported;
-#endif
+ return NvCtrlNvmlGetAttributePerms(h, attr_type, attr, &val->permissions);
}
@@ -1510,7 +1787,7 @@ NvCtrlNvmlGetValidStringAttributeValues(const CtrlTarget *ctrl_target,
* Get NVML Valid Attribute Values
*/
-#ifdef NVML_EXPERIMENTAL
+
static ReturnStatus
NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
@@ -1527,10 +1804,11 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
nvml = h->nvml;
+ val->permissions.write = NV_FALSE;
+
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
- case NV_CTRL_VIDEO_RAM:
case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
case NV_CTRL_PCI_DOMAIN:
@@ -1539,27 +1817,46 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
case NV_CTRL_PCI_FUNCTION:
case NV_CTRL_PCI_ID:
case NV_CTRL_GPU_PCIE_GENERATION:
- case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH:
- case NV_CTRL_GPU_PCIE_MAX_LINK_SPEED:
- case NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED:
- case NV_CTRL_BUS_TYPE:
+ case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
+ case NV_CTRL_GPU_SLOWDOWN_THRESHOLD:
+ case NV_CTRL_GPU_SHUTDOWN_THRESHOLD:
+ case NV_CTRL_GPU_CORE_TEMPERATURE:
case NV_CTRL_GPU_MEMORY_BUS_WIDTH:
case NV_CTRL_GPU_CORES:
case NV_CTRL_IRQ:
- case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
case NV_CTRL_GPU_POWER_SOURCE:
- case NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL:
- case NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE:
- case NV_CTRL_GPU_POWER_MIZER_MODE:
- case NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE:
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_INTEGER;
+ break;
+
case NV_CTRL_GPU_ECC_SUPPORTED:
case NV_CTRL_GPU_ECC_STATUS:
case NV_CTRL_GPU_ECC_CONFIGURATION:
- case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION:
+ case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_BOOL;
+ break;
+
+ case NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS:
case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS:
case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS:
- case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER;
+ break;
+
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS:
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_BITMASK;
+ break;
+
+ case NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION:
+ case NV_CTRL_VIDEO_RAM:
+ case NV_CTRL_GPU_PCIE_MAX_LINK_SPEED:
+ case NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED:
+ case NV_CTRL_BUS_TYPE:
+ case NV_CTRL_GPU_COOLER_MANUAL_CONTROL:
+ case NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL:
+ case NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE:
+ case NV_CTRL_GPU_POWER_MIZER_MODE:
+ case NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE:
case NV_CTRL_ENABLED_DISPLAYS:
case NV_CTRL_CONNECTED_DISPLAYS:
case NV_CTRL_MAX_SCREEN_WIDTH:
@@ -1574,10 +1871,8 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
case NV_CTRL_ATTR_NV_MINOR_VERSION:
case NV_CTRL_OPERATING_SYSTEM:
case NV_CTRL_NO_SCANOUT:
- case NV_CTRL_GPU_CORE_TEMPERATURE:
case NV_CTRL_AMBIENT_TEMPERATURE:
case NV_CTRL_GPU_CURRENT_CLOCK_FREQS:
- case NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS:
case NV_CTRL_VIDEO_ENCODER_UTILIZATION:
case NV_CTRL_VIDEO_DECODER_UTILIZATION:
case NV_CTRL_FRAMELOCK:
@@ -1599,7 +1894,7 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
* XXX We'll eventually need to add support for this attributes
* through NVML
*/
- return NvCtrlNotSupported;
+ return NvCtrlAttributeNotAvailable;
default:
/* The attribute queried is not GPU-targeted */
@@ -1613,7 +1908,7 @@ NvCtrlNvmlGetGPUValidAttributeValues(const CtrlTarget *ctrl_target, int attr,
/* An NVML error occurred */
printNvmlError(ret);
- return NvCtrlNotSupported;
+ return NvCtrlNoAttribute;
}
static ReturnStatus
@@ -1651,7 +1946,7 @@ NvCtrlNvmlGetThermalValidAttributeValues(const CtrlTarget *ctrl_target,
* XXX We'll eventually need to add support for this attributes
* through NVML
*/
- return NvCtrlNotSupported;
+ return NvCtrlAttributeNotAvailable;
default:
/* The attribute queried is not sensor-targeted */
@@ -1665,7 +1960,7 @@ NvCtrlNvmlGetThermalValidAttributeValues(const CtrlTarget *ctrl_target,
/* An NVML error occurred */
printNvmlError(ret);
- return NvCtrlNotSupported;
+ return NvCtrlNoAttribute;
}
static ReturnStatus
@@ -1696,6 +1991,13 @@ NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target,
ret = nvml->lib.deviceGetHandleByIndex(nvml->deviceIdx, &device);
if (ret == NVML_SUCCESS) {
switch (attr) {
+ case NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL:
+ /* Range as a percent */
+ val->valid_type = CTRL_ATTRIBUTE_VALID_TYPE_RANGE;
+ val->range.min = 0;
+ val->range.max = 100;
+ return NvCtrlSuccess;
+
case NV_CTRL_THERMAL_COOLER_LEVEL:
case NV_CTRL_THERMAL_COOLER_SPEED:
case NV_CTRL_THERMAL_COOLER_CONTROL_TYPE:
@@ -1704,7 +2006,7 @@ NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target,
* XXX We'll eventually need to add support for this attributes
* through NVML
*/
- return NvCtrlNotSupported;
+ return NvCtrlAttributeNotAvailable;
default:
/* The attribute queried is not fan-targeted */
@@ -1718,22 +2020,24 @@ NvCtrlNvmlGetCoolerValidAttributeValues(const CtrlTarget *ctrl_target,
/* An NVML error occurred */
printNvmlError(ret);
- return NvCtrlNotSupported;
+ return NvCtrlNoAttribute;
}
-#endif // NVML_EXPERIMENTAL
+
ReturnStatus
NvCtrlNvmlGetValidAttributeValues(const CtrlTarget *ctrl_target,
int attr,
CtrlAttributeValidValues *val)
{
+ const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
+ ReturnStatus ret = NvCtrlAttributeNotAvailable;
+ CtrlAttributeType attr_type;
+
if (NvmlMissing(ctrl_target)) {
return NvCtrlMissingExtension;
}
-#ifdef NVML_EXPERIMENTAL
- ReturnStatus ret;
/*
* This shouldn't be reached for target types that are not handled through
* NVML (Keep TARGET_TYPE_IS_NVML_COMPATIBLE in NvCtrlAttributesPrivate.h up
@@ -1764,30 +2068,136 @@ NvCtrlNvmlGetValidAttributeValues(const CtrlTarget *ctrl_target,
ret = NvCtrlBadHandle;
}
-
- /*
- * XXX Did we forgot to handle this attribute? - REMOVE THIS after
- * nvidia-settings NVML migration work is done
- */
- if (ret == NvCtrlAttributeNotAvailable) {
- const NvCtrlAttributePrivateHandle *h = getPrivateHandleConst(ctrl_target);
- ReturnStatus ret2;
+ if (ret != NvCtrlSuccess) {
+ return ret;
+ }
- if (!h->nv) {
- return NvCtrlMissingExtension;
- }
+ ret = convertValidTypeToAttributeType(val->valid_type, &attr_type);
+
+ if (ret != NvCtrlSuccess) {
+ return ret;
+ }
+
+ return NvCtrlNvmlGetAttributePerms(h, attr_type, attr, &val->permissions);
+}
+
+static ReturnStatus NvCtrlNvmlGetIntegerAttributePerms(int attr,
+ CtrlAttributePerms *perms)
+{
+ /* Set write permissions */
+ switch (attr) {
+ case NV_CTRL_GPU_ECC_CONFIGURATION:
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS:
+ perms->write = NV_TRUE;
+ break;
+ default:
+ perms->write = NV_FALSE;
+ }
+
+ /* Valid target and read permissions */
+ switch (attr) {
+ case NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY:
+ case NV_CTRL_USED_DEDICATED_GPU_MEMORY:
+ case NV_CTRL_PCI_DOMAIN:
+ case NV_CTRL_PCI_BUS:
+ case NV_CTRL_PCI_DEVICE:
+ case NV_CTRL_PCI_FUNCTION:
+ case NV_CTRL_PCI_ID:
+ case NV_CTRL_GPU_PCIE_GENERATION:
+ case NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH:
+ case NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH:
+ case NV_CTRL_GPU_SLOWDOWN_THRESHOLD:
+ case NV_CTRL_GPU_SHUTDOWN_THRESHOLD:
+ case NV_CTRL_GPU_CORE_TEMPERATURE:
+ case NV_CTRL_GPU_MEMORY_BUS_WIDTH:
+ case NV_CTRL_GPU_CORES:
+ case NV_CTRL_IRQ:
+ case NV_CTRL_GPU_POWER_SOURCE:
+ /* CTRL_ATTRIBUTE_VALID_TYPE_BOOL */
+ case NV_CTRL_GPU_ECC_SUPPORTED:
+ case NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED:
+ case NV_CTRL_GPU_ECC_STATUS:
+ case NV_CTRL_GPU_ECC_CONFIGURATION:
+ /* CTRL_ATTRIBUTE_VALID_TYPE_64BIT_INTEGER */
+ case NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS:
+ case NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS:
+ perms->read = NV_TRUE;
+ perms->valid_targets = CTRL_TARGET_PERM_BIT(GPU_TARGET);
+ break;
- ret2 = NvCtrlNvControlGetValidAttributeValues(h, 0, attr, val);
+ /* GPU_TARGET non-readable attribute */
+ case NV_CTRL_GPU_ECC_RESET_ERROR_STATUS:
+ perms->read = NV_FALSE;
+ perms->valid_targets = CTRL_TARGET_PERM_BIT(GPU_TARGET);
+ break;
- assert(ret2 == NvCtrlAttributeNotAvailable);
+ case NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL:
+ perms->valid_targets = CTRL_TARGET_PERM_BIT(COOLER_TARGET);
+ perms->read = NV_TRUE;
+ break;
- return ret2;
+ default:
+ perms->valid_targets = 0;
+ perms->read = NV_FALSE;
+ return NvCtrlNotSupported;
+ }
+
+ return NvCtrlSuccess;
+}
+
+static ReturnStatus NvCtrlNvmlGetStringAttributePerms(int attr,
+ CtrlAttributePerms *perms)
+{
+ perms->write = NV_FALSE;
+
+ switch (attr) {
+ case NV_CTRL_STRING_NVIDIA_DRIVER_VERSION:
+ case NV_CTRL_STRING_PRODUCT_NAME:
+ case NV_CTRL_STRING_VBIOS_VERSION:
+ case NV_CTRL_STRING_GPU_UUID:
+ perms->valid_targets = CTRL_TARGET_PERM_BIT(GPU_TARGET);
+ perms->read = NV_TRUE;
+ break;
+ default:
+ perms->valid_targets = 0;
+ perms->read = NV_FALSE;
+ return NvCtrlNotSupported;
+ }
+ return NvCtrlSuccess;
+}
+
+
+ReturnStatus
+NvCtrlNvmlGetAttributePerms(const NvCtrlAttributePrivateHandle *h,
+ CtrlAttributeType attr_type, int attr,
+ CtrlAttributePerms *perms)
+{
+ ReturnStatus ret = NvCtrlSuccess;
+
+ if (!h->nvml) {
+ return NvCtrlBadArgument;
+ }
+
+ switch (attr_type) {
+ case CTRL_ATTRIBUTE_TYPE_INTEGER:
+ ret = NvCtrlNvmlGetIntegerAttributePerms(attr, perms);
+ break;
+
+ case CTRL_ATTRIBUTE_TYPE_STRING:
+ ret = NvCtrlNvmlGetStringAttributePerms(attr, perms);
+ break;
+
+ case CTRL_ATTRIBUTE_TYPE_BINARY_DATA:
+ return NvCtrlBadArgument;
+ break;
+
+ default:
+ return NvCtrlBadArgument;
}
return ret;
-#else
- return NvCtrlNotSupported;
-#endif
}
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
index 1ce590f..d93e207 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
@@ -170,15 +170,31 @@ struct __NvCtrlNvmlAttributes {
typeof(nvmlDeviceGetUUID) (*deviceGetUUID);
typeof(nvmlDeviceGetCount) (*deviceGetCount);
typeof(nvmlDeviceGetTemperature) (*deviceGetTemperature);
- typeof(nvmlDeviceGetFanSpeed) (*deviceGetFanSpeed);
typeof(nvmlDeviceGetName) (*deviceGetName);
typeof(nvmlDeviceGetVbiosVersion) (*deviceGetVbiosVersion);
typeof(nvmlDeviceGetMemoryInfo) (*deviceGetMemoryInfo);
+ typeof(nvmlDeviceGetMemoryInfo_v2) (*deviceGetMemoryInfo_v2);
typeof(nvmlDeviceGetPciInfo) (*deviceGetPciInfo);
+ typeof(nvmlDeviceGetCurrPcieLinkWidth) (*deviceGetCurrPcieLinkWidth);
typeof(nvmlDeviceGetMaxPcieLinkGeneration) (*deviceGetMaxPcieLinkGeneration);
typeof(nvmlDeviceGetMaxPcieLinkWidth) (*deviceGetMaxPcieLinkWidth);
typeof(nvmlDeviceGetVirtualizationMode) (*deviceGetVirtualizationMode);
typeof(nvmlDeviceGetGridLicensableFeatures_v4) (*deviceGetGridLicensableFeatures);
+ typeof(nvmlDeviceGetUtilizationRates) (*deviceGetUtilizationRates);
+ typeof(nvmlDeviceGetTemperatureThreshold) (*deviceGetTemperatureThreshold);
+ typeof(nvmlDeviceGetFanSpeed_v2) (*deviceGetFanSpeed_v2);
+ typeof(nvmlSystemGetDriverVersion) (*systemGetDriverVersion);
+ typeof(nvmlDeviceGetEccMode) (*deviceGetEccMode);
+ typeof(nvmlDeviceSetEccMode) (*deviceSetEccMode);
+ typeof(nvmlDeviceGetTotalEccErrors) (*deviceGetTotalEccErrors);
+ typeof(nvmlDeviceClearEccErrorCounts) (*deviceClearEccErrorCounts);
+ typeof(nvmlDeviceGetMemoryErrorCounter) (*deviceGetMemoryErrorCounter);
+ typeof(nvmlSystemGetNVMLVersion) (*systemGetNVMLVersion);
+ typeof(nvmlDeviceGetNumGpuCores) (*deviceGetNumGpuCores);
+ typeof(nvmlDeviceGetMemoryBusWidth) (*deviceGetMemoryBusWidth);
+ typeof(nvmlDeviceGetIrqNum) (*deviceGetIrqNum);
+ typeof(nvmlDeviceGetPowerSource) (*deviceGetPowerSource);
+ typeof(nvmlDeviceGetNumFans) (*deviceGetNumFans);
} lib;
@@ -457,4 +473,9 @@ NvCtrlNvmlGetValidAttributeValues(const CtrlTarget *ctrl_target,
int attr,
CtrlAttributeValidValues *val);
+ReturnStatus
+NvCtrlNvmlGetAttributePerms(const NvCtrlAttributePrivateHandle *,
+ CtrlAttributeType, int,
+ CtrlAttributePerms *);
+
#endif /* __NVCTRL_ATTRIBUTES_PRIVATE__ */
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c b/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c
index 5acb7c3..111b24c 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesUtils.c
@@ -505,7 +505,9 @@ static void add_target_relationships(CtrlTarget *target,
status = NvCtrlGetBinaryAttribute(target, 0, attr,
(unsigned char **)(&pData), &len);
if ((status != NvCtrlSuccess) || !pData) {
- nv_error_msg("Error querying target relations");
+ if (status != NvCtrlNotSupported) {
+ nv_error_msg("Error querying target relations");
+ }
return;
}
@@ -673,7 +675,7 @@ static CtrlTarget *nv_alloc_ctrl_target(CtrlSystem *system,
* not being specified in xorg.conf, it can cause errors down the line.
*/
- if (target_type == GPU_TARGET) {
+ if (target_type == GPU_TARGET && t->system->has_nv_control) {
/* NV_CTRL_DEPTH_30_ALLOWED expected to succeed for any valid device */
status = NvCtrlGetAttribute(t, NV_CTRL_DEPTH_30_ALLOWED, &d);
if (status != NvCtrlSuccess) {
@@ -733,7 +735,7 @@ static CtrlTarget *nv_alloc_ctrl_target(CtrlSystem *system,
* (framelock), we just assign this to 0.
*/
- if (targetTypeInfo->uses_display_devices) {
+ if (targetTypeInfo->uses_display_devices && system->has_nv_control) {
status = NvCtrlGetAttribute(t,
NV_CTRL_ENABLED_DISPLAYS, &d);
@@ -817,6 +819,16 @@ static Bool is_nvcontrol_protocol_valid(const CtrlTarget *ctrl_target,
}
+static const char *get_display_name(CtrlSystem *system)
+{
+ if (system->has_nv_control) {
+ return XDisplayName(system->display);
+ } else {
+ return system->display;
+ }
+}
+
+
static Bool load_system_info(CtrlSystem *system, const char *display)
{
ReturnStatus status;
@@ -826,6 +838,8 @@ static Bool load_system_info(CtrlSystem *system, const char *display)
int unused;
int *pData = NULL;
const CtrlTargetTypeInfo *targetTypeInfo;
+ int subsystems = NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM |
+ NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM;
if (!system) {
return FALSE;
@@ -841,19 +855,19 @@ static Bool load_system_info(CtrlSystem *system, const char *display)
system->dpy = XOpenDisplay(system->display);
if (system->dpy == NULL) {
- nv_error_msg("Unable to find display on any available system");
- return FALSE;
+ /* If it fails, just use NVML */
+ subsystems = NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM;
+ } else {
+ system->has_nv_control =
+ XNVCTRLQueryExtension(system->dpy, &unused, &unused);
}
- system->has_nv_control =
- XNVCTRLQueryExtension(system->dpy, &unused, &unused);
-
/* Try to initialize the NVML library */
- nvmlQueryTarget = nv_alloc_ctrl_target(system, GPU_TARGET, 0,
- NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM |
- NV_CTRL_ATTRIBUTES_NVML_SUBSYSTEM);
+ nvmlQueryTarget = nv_alloc_ctrl_target(system, GPU_TARGET, 0, subsystems);
- if (nvmlQueryTarget == NULL) {
+ system->has_nvml = (nvmlQueryTarget != NULL);
+
+ if (system->has_nvml == FALSE) {
nv_error_msg("Unable to load info from any available system");
return FALSE;
}
@@ -888,7 +902,9 @@ static Bool load_system_info(CtrlSystem *system, const char *display)
status = NvCtrlQueryTargetCount(nvmlQueryTarget,
target_type,
&val);
- target_count = val;
+ if (status == NvCtrlSuccess) {
+ target_count = val;
+ }
}
else if ((h != NULL) && (h->nvml != NULL) &&
@@ -950,7 +966,7 @@ static Bool load_system_info(CtrlSystem *system, const char *display)
nv_warning_msg("Unable to determine number of NVIDIA "
"%ss on '%s'.",
targetTypeInfo->name,
- XDisplayName(system->display));
+ get_display_name(system));
val = 0;
}
@@ -1026,7 +1042,7 @@ static Bool load_system_info(CtrlSystem *system, const char *display)
if (status != NvCtrlSuccess) {
nv_warning_msg("Unable to determine number of NVIDIA %ss on '%s'.",
- targetTypeInfo->name, XDisplayName(system->display));
+ targetTypeInfo->name, get_display_name(system));
val = 0;
}