- Disabled retain support by default, you can reactive it using --gpu-temp-retain
- Completely get rid of HAVE_ADL, HAVE_NVML and HAVE_NVAPI in sources
- Replaced NVAPI with NVML on windows
+- Added support for XNVCTRL on Linux to add support for --gpu-temp-retain for NVidia GPU
typedef void *ADL_LIB;
typedef void *NVAPI_LIB;
typedef void *NVML_LIB;
+typedef void *XNVCTRL_LIB;
#ifdef OSX
#define __stdcall
#endif
typedef HINSTANCE ADL_LIB;
typedef HINSTANCE NVAPI_LIB;
typedef HINSTANCE NVML_LIB;
+typedef HINSTANCE XNVCTRL_LIB;
#endif
#define mkdir(name,mode) mkdir (name)
--- /dev/null
+/**
+ * Authors.....: Jens Steube <jens.steube@gmail.com>
+ * License.....: MIT
+ */
+
+#ifndef EXT_XNVCTRL_H
+#define EXT_XNVCTRL_H
+
+#if defined(HAVE_HWMON)
+
+#include <common.h>
+
+/**
+ * Stuff from X11/Xlib.h
+ */
+
+typedef void *(*XOPENDISPLAY) (char *);
+typedef int (*XCLOSEDISPLAY) (void *);
+
+/**
+ * Declarations from NVCtrl.h
+ */
+
+#define NV_CTRL_TARGET_TYPE_GPU 1
+#define NV_CTRL_TARGET_TYPE_COOLER 5 /* e.g., fan */
+
+#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL 319 /* RW-G */
+#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_FALSE 0
+#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE 1
+
+#define NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL 417 /* R--C */
+#define NV_CTRL_THERMAL_COOLER_LEVEL 320 /* RW-C */
+
+/*
+ * NV_CTRL_GPU_CORE_THRESHOLD reflects the temperature at which the
+ * GPU is throttled to prevent overheating.
+ */
+
+#define NV_CTRL_GPU_CORE_THRESHOLD 61 /* R--G */
+
+/**
+ * hashcat stuff from here
+ */
+
+typedef int HM_ADAPTER_XNVCTRL;
+
+#include <shared.h>
+
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#define XNVCTRL_API_CALL __stdcall
+#else
+#define XNVCTRL_API_CALL
+#endif
+
+typedef int (*XNVCTRL_API_CALL XNVCTRLQUERYTARGETATTRIBUTE) (void *, int, int, unsigned int, unsigned int, int *);
+typedef void (*XNVCTRL_API_CALL XNVCTRLSETTARGETATTRIBUTE) (void *, int, int, unsigned int, unsigned int, int);
+
+typedef struct
+{
+ void *dpy;
+
+ XNVCTRL_LIB lib_x11;
+ XNVCTRL_LIB lib_xnvctrl;
+
+ XOPENDISPLAY XOpenDisplay;
+ XCLOSEDISPLAY XCloseDisplay;
+
+ XNVCTRLQUERYTARGETATTRIBUTE XNVCTRLQueryTargetAttribute;
+ XNVCTRLSETTARGETATTRIBUTE XNVCTRLSetTargetAttribute;
+
+} hm_xnvctrl_lib_t;
+
+#define XNVCTRL_PTR hm_xnvctrl_lib_t
+
+int xnvctrl_init (XNVCTRL_PTR *xnvctrl);
+void xnvctrl_close (XNVCTRL_PTR *xnvctrl);
+
+int hm_XNVCTRL_XOpenDisplay (XNVCTRL_PTR *xnvctrl);
+void hm_XNVCTRL_XCloseDisplay (XNVCTRL_PTR *xnvctrl);
+
+int get_core_threshold (XNVCTRL_PTR *xnvctrl, int gpu, int *val);
+
+int get_fan_control (XNVCTRL_PTR *xnvctrl, int gpu, int *val);
+int set_fan_control (XNVCTRL_PTR *xnvctrl, int gpu, int val);
+
+int get_fan_speed_current (XNVCTRL_PTR *xnvctrl, int gpu, int *val);
+int get_fan_speed_target (XNVCTRL_PTR *xnvctrl, int gpu, int *val);
+int set_fan_speed_target (XNVCTRL_PTR *xnvctrl, int gpu, int val);
+
+#endif // HAVE_HWMON
+
+#endif // EXT_XNVCTRL_H
#include "ext_ADL.h"
#include "ext_nvapi.h"
#include "ext_nvml.h"
+#include "ext_xnvctrl.h"
/**
* shared stuff
int hm_get_corespeed_with_device_id (const uint device_id);
int hm_get_throttle_with_device_id (const uint device_id);
int hm_set_fanspeed_with_device_id_adl (const uint device_id, const int fanspeed, const int fanpolicy);
+int hm_set_fanspeed_with_device_id_xnvctrl (const uint device_id, const int fanspeed);
void hm_device_val_to_str (char *target_buf, int max_buf_size, char *suffix, int value);
#endif // HAVE_HWMON
#ifdef HAVE_HWMON
typedef struct
{
- HM_ADAPTER_ADL adl;
- HM_ADAPTER_NVML nvml;
- HM_ADAPTER_NVAPI nvapi;
+ HM_ADAPTER_ADL adl;
+ HM_ADAPTER_NVML nvml;
+ HM_ADAPTER_NVAPI nvapi;
+ HM_ADAPTER_XNVCTRL xnvctrl;
int od_version;
void *hm_adl;
void *hm_nvml;
void *hm_nvapi;
+ void *hm_xnvctrl;
hm_attrs_t hm_device[DEVICES_MAX];
#endif
NATIVE_OBJS += obj/ext_ADL.NATIVE.o
NATIVE_OBJS += obj/ext_nvapi.NATIVE.o
NATIVE_OBJS += obj/ext_nvml.NATIVE.o
+NATIVE_OBJS += obj/ext_xnvctrl.NATIVE.o
endif
-LINUX_32_OBJS := obj/ext_OpenCL.LINUX.32.o obj/shared.LINUX.32.o obj/rp_kernel_on_cpu.LINUX.32.o obj/ext_ADL.LINUX.32.o obj/ext_nvml.LINUX.32.o obj/ext_nvapi.LINUX.32.o
-LINUX_64_OBJS := obj/ext_OpenCL.LINUX.64.o obj/shared.LINUX.64.o obj/rp_kernel_on_cpu.LINUX.64.o obj/ext_ADL.LINUX.64.o obj/ext_nvml.LINUX.64.o obj/ext_nvapi.LINUX.64.o
+LINUX_32_OBJS := obj/ext_OpenCL.LINUX.32.o obj/shared.LINUX.32.o obj/rp_kernel_on_cpu.LINUX.32.o obj/ext_ADL.LINUX.32.o obj/ext_nvml.LINUX.32.o obj/ext_nvapi.LINUX.32.o obj/ext_xnvctrl.LINUX.32.o
+LINUX_64_OBJS := obj/ext_OpenCL.LINUX.64.o obj/shared.LINUX.64.o obj/rp_kernel_on_cpu.LINUX.64.o obj/ext_ADL.LINUX.64.o obj/ext_nvml.LINUX.64.o obj/ext_nvapi.LINUX.64.o obj/ext_xnvctrl.LINUX.64.o
## may need to adjust according to your mingw distribution
CRT_GLOB_32 := /usr/i686-w64-mingw32/lib/CRT_glob.o
CRT_GLOB_64 := /usr/x86_64-w64-mingw32/lib/CRT_glob.o
-WIN_32_OBJS := obj/ext_OpenCL.WIN.32.o obj/shared.WIN.32.o obj/rp_kernel_on_cpu.WIN.32.o obj/ext_ADL.WIN.32.o obj/ext_nvml.WIN.32.o obj/ext_nvapi.WIN.32.o $(CRT_GLOB_32)
-WIN_64_OBJS := obj/ext_OpenCL.WIN.64.o obj/shared.WIN.64.o obj/rp_kernel_on_cpu.WIN.64.o obj/ext_ADL.WIN.64.o obj/ext_nvml.WIN.64.o obj/ext_nvapi.WIN.64.o $(CRT_GLOB_64)
+WIN_32_OBJS := obj/ext_OpenCL.WIN.32.o obj/shared.WIN.32.o obj/rp_kernel_on_cpu.WIN.32.o obj/ext_ADL.WIN.32.o obj/ext_nvml.WIN.32.o obj/ext_nvapi.WIN.32.o obj/ext_xnvctrl.WIN.32.o $(CRT_GLOB_32)
+WIN_64_OBJS := obj/ext_OpenCL.WIN.64.o obj/shared.WIN.64.o obj/rp_kernel_on_cpu.WIN.64.o obj/ext_ADL.WIN.64.o obj/ext_nvml.WIN.64.o obj/ext_nvapi.WIN.64.o obj/ext_xnvctrl.WIN.64.o $(CRT_GLOB_64)
##
## Targets: Global
--- /dev/null
+/**
+ * Authors.....: Jens Steube <jens.steube@gmail.com>
+ * License.....: MIT
+ */
+
+#include <ext_xnvctrl.h>
+
+int xnvctrl_init (XNVCTRL_PTR *xnvctrl)
+{
+ if (!xnvctrl) return (-1);
+
+ memset (xnvctrl, 0, sizeof (XNVCTRL_PTR));
+
+ #ifdef _WIN
+
+ // unsupport platform?
+ return (-1);
+
+ #elif _POSIX
+
+ xnvctrl->lib_x11 = dlopen ("libX11.so", RTLD_LAZY);
+
+ if (xnvctrl->lib_x11 == NULL)
+ {
+ if (data.quiet == 0) log_info ("WARNING: load X11 library failed, proceed without X11 HWMon enabled.");
+
+ return -1;
+ }
+
+ xnvctrl->lib_xnvctrl = dlopen ("libXNVCtrl.so", RTLD_LAZY);
+
+ if (xnvctrl->lib_xnvctrl == NULL)
+ {
+ xnvctrl->lib_xnvctrl = dlopen ("libXNVCtrl.so.0", RTLD_LAZY);
+
+ if (xnvctrl->lib_xnvctrl == NULL)
+ {
+ if (data.quiet == 0) log_info ("WARNING: load XNVCTRL library failed, proceed without XNVCTRL HWMon enabled.");
+
+ return -1;
+ }
+ }
+
+ xnvctrl->XOpenDisplay = dlsym (xnvctrl->lib_x11, "XOpenDisplay");
+ xnvctrl->XCloseDisplay = dlsym (xnvctrl->lib_x11, "XCloseDisplay");
+
+ xnvctrl->XNVCTRLQueryTargetAttribute = dlsym (xnvctrl->lib_xnvctrl, "XNVCTRLQueryTargetAttribute");
+ xnvctrl->XNVCTRLSetTargetAttribute = dlsym (xnvctrl->lib_xnvctrl, "XNVCTRLSetTargetAttribute");
+
+ #endif
+
+ // not using HC_LOAD_FUNC() here, because we're using 2 libraries and therefore have 2 different variable names for them
+
+ return 0;
+}
+
+void xnvctrl_close (XNVCTRL_PTR *xnvctrl)
+{
+ if (xnvctrl)
+ {
+ #if _POSIX
+
+ if (xnvctrl->lib_x11)
+ {
+ dlclose (xnvctrl->lib_x11);
+ }
+
+ if (xnvctrl->lib_xnvctrl)
+ {
+ dlclose (xnvctrl->lib_xnvctrl);
+ }
+
+ #endif
+
+ myfree (xnvctrl);
+ }
+}
+
+int hm_XNVCTRL_XOpenDisplay (XNVCTRL_PTR *xnvctrl)
+{
+ void *dpy = xnvctrl->XOpenDisplay (NULL);
+
+ if (dpy == NULL)
+ {
+ return -1;
+ }
+
+ xnvctrl->dpy = dpy;
+
+ return 0;
+}
+
+void hm_XNVCTRL_XCloseDisplay (XNVCTRL_PTR *xnvctrl)
+{
+ xnvctrl->XCloseDisplay (xnvctrl->dpy);
+}
+
+int get_fan_control (XNVCTRL_PTR *xnvctrl, int gpu, int *val)
+{
+ int rc = xnvctrl->XNVCTRLQueryTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, 0, NV_CTRL_GPU_COOLER_MANUAL_CONTROL, val);
+
+ if (!rc) return -1;
+
+ return 0;
+}
+
+int set_fan_control (XNVCTRL_PTR *xnvctrl, int gpu, int val)
+{
+ xnvctrl->XNVCTRLSetTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, 0, NV_CTRL_GPU_COOLER_MANUAL_CONTROL, val);
+
+ int cur;
+
+ int rc = get_fan_control (xnvctrl, gpu, &cur);
+
+ if (rc == -1) return -1;
+
+ if (cur != val) return -1;
+
+ return 0;
+}
+
+int get_core_threshold (XNVCTRL_PTR *xnvctrl, int gpu, int *val)
+{
+ int rc = xnvctrl->XNVCTRLQueryTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, 0, NV_CTRL_GPU_CORE_THRESHOLD, val);
+
+ if (!rc) return -1;
+
+ return 0;
+}
+
+int get_fan_speed_current (XNVCTRL_PTR *xnvctrl, int gpu, int *val)
+{
+ int rc = xnvctrl->XNVCTRLQueryTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_COOLER, gpu, 0, NV_CTRL_THERMAL_COOLER_CURRENT_LEVEL, val);
+
+ if (!rc) return -1;
+
+ return 0;
+}
+
+int get_fan_speed_target (XNVCTRL_PTR *xnvctrl, int gpu, int *val)
+{
+ int rc = xnvctrl->XNVCTRLQueryTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_COOLER, gpu, 0, NV_CTRL_THERMAL_COOLER_LEVEL, val);
+
+ if (!rc) return -1;
+
+ return 0;
+}
+
+int set_fan_speed_target (XNVCTRL_PTR *xnvctrl, int gpu, int val)
+{
+ xnvctrl->XNVCTRLSetTargetAttribute (xnvctrl->dpy, NV_CTRL_TARGET_TYPE_COOLER, gpu, 0, NV_CTRL_THERMAL_COOLER_LEVEL, val);
+
+ int cur;
+
+ int rc = get_fan_speed_target (xnvctrl, gpu, &cur);
+
+ if (rc == -1) return -1;
+
+ if (cur != val) return -1;
+
+ return 0;
+}
}
else if (device_param->device_vendor_id == VENDOR_ID_NV)
{
-
+ #ifdef _POSIX
+ hm_set_fanspeed_with_device_id_xnvctrl (device_id, fan_speed_new);
+ #endif
}
fan_speed_chgd[device_id] = 1;
* OpenCL devices: simply push all devices from all platforms into the same device array
*/
- int need_adl = 0;
- int need_nvapi = 0;
- int need_nvml = 0;
+ int need_adl = 0;
+ int need_nvapi = 0;
+ int need_nvml = 0;
+ int need_xnvctrl = 0;
hc_device_param_t *devices_param = (hc_device_param_t *) mycalloc (DEVICES_MAX, sizeof (hc_device_param_t));
{
need_nvml = 1;
+ #ifdef _POSIX
+ need_xnvctrl = 1;
+ #endif
+
#ifdef _WIN
need_nvapi = 1;
#endif
*/
#ifdef HAVE_HWMON
- hm_attrs_t hm_adapters_adl[DEVICES_MAX] = { { 0 } };
- hm_attrs_t hm_adapters_nvapi[DEVICES_MAX] = { { 0 } };
- hm_attrs_t hm_adapters_nvml[DEVICES_MAX] = { { 0 } };
+ hm_attrs_t hm_adapters_adl[DEVICES_MAX] = { { 0 } };
+ hm_attrs_t hm_adapters_nvapi[DEVICES_MAX] = { { 0 } };
+ hm_attrs_t hm_adapters_nvml[DEVICES_MAX] = { { 0 } };
+ hm_attrs_t hm_adapters_xnvctrl[DEVICES_MAX] = { { 0 } };
if (gpu_temp_disable == 0)
{
- ADL_PTR *adl = (ADL_PTR *) mymalloc (sizeof (ADL_PTR));
- NVAPI_PTR *nvapi = (NVAPI_PTR *) mymalloc (sizeof (NVAPI_PTR));
- NVML_PTR *nvml = (NVML_PTR *) mymalloc (sizeof (NVML_PTR));
+ ADL_PTR *adl = (ADL_PTR *) mymalloc (sizeof (ADL_PTR));
+ NVAPI_PTR *nvapi = (NVAPI_PTR *) mymalloc (sizeof (NVAPI_PTR));
+ NVML_PTR *nvml = (NVML_PTR *) mymalloc (sizeof (NVML_PTR));
+ XNVCTRL_PTR *xnvctrl = (XNVCTRL_PTR *) mymalloc (sizeof (XNVCTRL_PTR));
- data.hm_adl = NULL;
- data.hm_nvapi = NULL;
- data.hm_nvml = NULL;
+ data.hm_adl = NULL;
+ data.hm_nvapi = NULL;
+ data.hm_nvml = NULL;
+ data.hm_xnvctrl = NULL;
if ((need_nvml == 1) && (nvml_init (nvml) == 0))
{
}
}
+ if ((need_xnvctrl == 1) && (xnvctrl_init (xnvctrl) == 0))
+ {
+ data.hm_xnvctrl = xnvctrl;
+ }
+
+ if (data.hm_xnvctrl)
+ {
+ if (hm_XNVCTRL_XOpenDisplay (data.hm_xnvctrl) == 0)
+ {
+ for (uint device_id = 0; device_id < data.devices_cnt; device_id++)
+ {
+ hc_device_param_t *device_param = &data.devices_param[device_id];
+
+ if ((device_param->device_type & CL_DEVICE_TYPE_GPU) == 0) continue;
+
+ hm_adapters_xnvctrl[device_id].xnvctrl = device_id;
+
+ int speed = 0;
+
+ if (get_fan_speed_current (data.hm_xnvctrl, device_id, &speed) == 0) hm_adapters_xnvctrl[device_id].fan_get_supported = 1;
+ }
+ }
+ }
+
if ((need_adl == 1) && (adl_init (adl) == 0))
{
data.hm_adl = adl;
}
}
- if (data.hm_adl == NULL && data.hm_nvml == NULL)
+ if (data.hm_adl == NULL && data.hm_nvml == NULL && data.hm_xnvctrl)
{
gpu_temp_disable = 1;
}
*/
#ifdef HAVE_HWMON
- if (gpu_temp_disable == 0 && data.hm_adl == NULL && data.hm_nvml == NULL)
+ if (gpu_temp_disable == 0 && data.hm_adl == NULL && data.hm_nvml == NULL && data.hm_xnvctrl == NULL)
{
log_info ("Watchdog: Hardware Monitoring Interface not found on your system");
}
data.hm_device[device_id].adl = hm_adapters_adl[platform_devices_id].adl;
data.hm_device[device_id].nvapi = 0;
data.hm_device[device_id].nvml = 0;
+ data.hm_device[device_id].xnvctrl = 0;
data.hm_device[device_id].od_version = hm_adapters_adl[platform_devices_id].od_version;
data.hm_device[device_id].fan_get_supported = hm_adapters_adl[platform_devices_id].fan_get_supported;
data.hm_device[device_id].fan_set_supported = hm_adapters_adl[platform_devices_id].fan_set_supported;
data.hm_device[device_id].adl = 0;
data.hm_device[device_id].nvapi = hm_adapters_nvapi[platform_devices_id].nvapi;
data.hm_device[device_id].nvml = hm_adapters_nvml[platform_devices_id].nvml;
+ data.hm_device[device_id].xnvctrl = hm_adapters_xnvctrl[platform_devices_id].xnvctrl;
data.hm_device[device_id].od_version = 0;
data.hm_device[device_id].fan_get_supported = hm_adapters_nvml[platform_devices_id].fan_get_supported;
data.hm_device[device_id].fan_set_supported = 0;
}
else if (device_param->device_vendor_id == VENDOR_ID_NV)
{
-
+ #ifdef _POSIX
+ rc = hm_set_fanspeed_with_device_id_xnvctrl (device_id, fanspeed);
+ #endif
}
if (rc == 0)
}
else if (device_param->device_vendor_id == VENDOR_ID_NV)
{
-
+ #ifdef _POSIX
+ rc = set_fan_control (data.hm_xnvctrl, data.hm_device[device_id].xnvctrl, NV_CTRL_GPU_COOLER_MANUAL_CONTROL_FALSE);
+ #endif
}
if (rc == -1) log_info ("WARNING: Failed to restore default fan speed and policy for device #%", device_id + 1);
data.hm_nvml = NULL;
}
+ if (data.hm_nvapi)
+ {
+ hm_NvAPI_Unload (data.hm_nvapi);
+
+ nvapi_close (data.hm_nvapi);
+
+ data.hm_nvapi = NULL;
+ }
+
+ if (data.hm_xnvctrl)
+ {
+ hm_XNVCTRL_XCloseDisplay (data.hm_xnvctrl);
+
+ xnvctrl_close (data.hm_xnvctrl);
+
+ data.hm_xnvctrl = NULL;
+ }
+
if (data.hm_adl)
{
hm_ADL_Main_Control_Destroy (data.hm_adl);
if (data.devices_param[device_id].device_vendor_id == VENDOR_ID_NV)
{
#if defined(LINUX)
- return 0;
+ if (data.hm_xnvctrl)
+ {
+ if (set_fan_control (data.hm_xnvctrl, data.hm_device[device_id].xnvctrl, NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE) != 0) return -1;
+
+ return 1;
+ }
#endif
#if defined(WIN)
return -1;
}
+int hm_set_fanspeed_with_device_id_xnvctrl (const uint device_id, const int fanspeed)
+{
+ if (data.hm_device[device_id].fan_set_supported == 1)
+ {
+ if (data.hm_xnvctrl)
+ {
+ if (set_fan_speed_target (data.hm_xnvctrl, data.hm_device[device_id].xnvctrl, fanspeed) != 0) return -1;
+
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
int hm_set_fanspeed_with_device_id_adl (const uint device_id, const int fanspeed, const int fanpolicy)
{
if (data.hm_device[device_id].fan_set_supported == 1)