diff --git a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py index 124d369300..eb119f8b5f 100644 --- a/projects/amdsmi/amdsmi_cli/amdsmi_commands.py +++ b/projects/amdsmi/amdsmi_cli/amdsmi_commands.py @@ -319,7 +319,7 @@ class AMDSMICommands(): if args.driver: try: driver_info = {} - driver_info['driver_version'] = amdsmi_interface.amdsmi_get_gpu_driver_version(args.gpu) + driver_info = amdsmi_interface.amdsmi_get_gpu_driver_info(args.gpu) static_dict['driver'] = driver_info except amdsmi_exception.AmdSmiLibraryException as e: diff --git a/projects/amdsmi/example/amd_smi_drm_example.cc b/projects/amdsmi/example/amd_smi_drm_example.cc index d8e71a601b..6b5767742a 100644 --- a/projects/amdsmi/example/amd_smi_drm_example.cc +++ b/projects/amdsmi/example/amd_smi_drm_example.cc @@ -314,12 +314,12 @@ int main() { printf("\tGPU Power limit: %d\n\n", power_measure.power_limit); // Get driver version - char version[AMDSMI_MAX_DRIVER_VERSION_LENGTH]; - int version_length = AMDSMI_MAX_DRIVER_VERSION_LENGTH; - ret = amdsmi_get_gpu_driver_version(processor_handles[j], &version_length, version); + amdsmi_driver_info_t driver_info; + ret = amdsmi_get_gpu_driver_info(processor_handles[j], &driver_info); CHK_AMDSMI_RET(ret) - printf(" Output of amdsmi_get_gpu_driver_version:\n"); - printf("\tDriver version: %s\n\n", version); + printf(" Output of amdsmi_get_gpu_driver_info:\n"); + printf("\tDriver version: %s\n", driver_info.driver_version); + printf("\tDriver date: %s\n\n", driver_info.driver_date); // Get device uuid unsigned int uuid_length = AMDSMI_GPU_UUID_SIZE; diff --git a/projects/amdsmi/include/amd_smi/amdsmi.h b/projects/amdsmi/include/amd_smi/amdsmi.h index 3a2b082bdb..679e54aab8 100644 --- a/projects/amdsmi/include/amd_smi/amdsmi.h +++ b/projects/amdsmi/include/amd_smi/amdsmi.h @@ -375,6 +375,11 @@ typedef struct { uint32_t reserved[3]; } amdsmi_asic_info_t; +typedef struct { + char driver_version[AMDSMI_MAX_STRING_LENGTH]; + char driver_date[AMDSMI_MAX_STRING_LENGTH]; +} amdsmi_driver_info_t; + typedef struct { uint64_t serial_number; bool is_master; @@ -3205,13 +3210,13 @@ amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned in * string buffer. As output parameter length of the returned * string buffer. * - * @param[out] version Version information in string format. Must be + * @param[out] info Reference to driver information structure. Must be * allocated by user. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *length, char *version); +amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle, amdsmi_driver_info_t *info); /** @} End swversion */ diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_drm.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_drm.h index d38740c056..cb9fde0c42 100644 --- a/projects/amdsmi/include/amd_smi/impl/amd_smi_drm.h +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_drm.h @@ -45,6 +45,7 @@ #define AMD_SMI_INCLUDE_IMPL_AMD_SMI_DRM_H_ #include +#include #include #include #include // NOLINT @@ -74,6 +75,7 @@ class AMDSmiDrm { amdsmi_status_t amdgpu_query_hw_ip(int fd, unsigned info_id, unsigned hw_ip_type, unsigned size, void *value); amdsmi_status_t amdgpu_query_vbios(int fd, void *info); + amdsmi_status_t amdgpu_query_driver_date(int fd, std::string& driver_date); private: // when file is not found, the empty string will be returned @@ -87,6 +89,11 @@ class AMDSmiDrm { AMDSmiLibraryLoader lib_loader_; // lazy load libdrm DrmCmdWriteFunc drm_cmd_write_; // drmCommandWrite + using drmGetVersionFunc = drmVersionPtr (*)(int); // drmGetVersion + using drmFreeVersionFunc = void (*)(drmVersionPtr); // drmFreeVersion + drmGetVersionFunc drm_get_version_; + drmFreeVersionFunc drm_free_version_; + std::mutex drm_mutex_; }; diff --git a/projects/amdsmi/include/amd_smi/impl/amd_smi_gpu_device.h b/projects/amdsmi/include/amd_smi/impl/amd_smi_gpu_device.h index 002e177146..fdd97d8cfd 100644 --- a/projects/amdsmi/include/amd_smi/impl/amd_smi_gpu_device.h +++ b/projects/amdsmi/include/amd_smi/impl/amd_smi_gpu_device.h @@ -81,6 +81,7 @@ class AMDSmiGPUDevice: public AMDSmiProcessor { amdsmi_status_t amdgpu_query_fw(unsigned info_id, unsigned fw_type, unsigned size, void *value) const; amdsmi_status_t amdgpu_query_vbios(void *info) const; + amdsmi_status_t amdgpu_query_driver_date(std::string& date) const; private: uint32_t gpu_id_; uint32_t fd_; diff --git a/projects/amdsmi/py-interface/README.md b/projects/amdsmi/py-interface/README.md index ab7f162110..9eec994c77 100644 --- a/projects/amdsmi/py-interface/README.md +++ b/projects/amdsmi/py-interface/README.md @@ -302,17 +302,17 @@ except AmdSmiException as e: print(e) ``` -### amdsmi_get_gpu_driver_version +### amdsmi_get_gpu_driver_info -Description: Returns the version string of the driver +Description: Returns the info of the driver Input parameters: * `processor_handle` dev for which to query -Output: Driver version string that is handling the device +Output: Driver info that is handling the device -Exceptions that can be thrown by `amdsmi_get_gpu_driver_version` function: +Exceptions that can be thrown by `amdsmi_get_gpu_driver_info` function: * `AmdSmiParameterException` * `AmdSmiLibraryException` @@ -322,7 +322,7 @@ Example: ```python try: device = amdsmi_get_processor_handles()[0] - print("Driver version: ", amdsmi_get_gpu_driver_version(device)) + print("Driver info: ", amdsmi_get_gpu_driver_info(device)) except AmdSmiException as e: print(e) ``` diff --git a/projects/amdsmi/py-interface/__init__.py b/projects/amdsmi/py-interface/__init__.py index 16a73ac8d9..61243ab046 100644 --- a/projects/amdsmi/py-interface/__init__.py +++ b/projects/amdsmi/py-interface/__init__.py @@ -34,7 +34,7 @@ from .amdsmi_interface import amdsmi_get_gpu_device_uuid from .amdsmi_interface import amdsmi_get_processor_handle_from_bdf # # SW Version Information -from .amdsmi_interface import amdsmi_get_gpu_driver_version +from .amdsmi_interface import amdsmi_get_gpu_driver_info # # ASIC and Bus Static Information from .amdsmi_interface import amdsmi_get_gpu_asic_info diff --git a/projects/amdsmi/py-interface/amdsmi_interface.py b/projects/amdsmi/py-interface/amdsmi_interface.py index 5ab5ad4be4..b3f6296cfc 100644 --- a/projects/amdsmi/py-interface/amdsmi_interface.py +++ b/projects/amdsmi/py-interface/amdsmi_interface.py @@ -917,9 +917,9 @@ def amdsmi_get_gpu_device_uuid(processor_handle: amdsmi_wrapper.amdsmi_processor return uuid.value.decode("utf-8") -def amdsmi_get_gpu_driver_version( +def amdsmi_get_gpu_driver_info( processor_handle: amdsmi_wrapper.amdsmi_processor_handle, -) -> str: +) -> Dict[str, Any]: if not isinstance(processor_handle, amdsmi_wrapper.amdsmi_processor_handle): raise AmdSmiParameterException( processor_handle, amdsmi_wrapper.amdsmi_processor_handle @@ -930,13 +930,17 @@ def amdsmi_get_gpu_driver_version( version = ctypes.create_string_buffer(_AMDSMI_MAX_DRIVER_VERSION_LENGTH) + info = amdsmi_wrapper.amdsmi_driver_info_t() _check_res( - amdsmi_wrapper.amdsmi_get_gpu_driver_version( - processor_handle, ctypes.byref(length), version + amdsmi_wrapper.amdsmi_get_gpu_driver_info( + processor_handle, ctypes.byref(info) ) ) - return version.value.decode("utf-8") + return { + "driver_version": info.driver_version.decode("utf-8"), + "driver_date": info.driver_date.decode("utf-8") + } def amdsmi_get_power_info( diff --git a/projects/amdsmi/py-interface/amdsmi_wrapper.py b/projects/amdsmi/py-interface/amdsmi_wrapper.py index 9b84553aae..488f68854f 100644 --- a/projects/amdsmi/py-interface/amdsmi_wrapper.py +++ b/projects/amdsmi/py-interface/amdsmi_wrapper.py @@ -675,6 +675,16 @@ struct_c__SA_amdsmi_asic_info_t._fields_ = [ ] amdsmi_asic_info_t = struct_c__SA_amdsmi_asic_info_t +class struct_c__SA_amdsmi_driver_info_t(Structure): + pass + +struct_c__SA_amdsmi_driver_info_t._pack_ = 1 # source:False +struct_c__SA_amdsmi_driver_info_t._fields_ = [ + ('driver_version', ctypes.c_char * 64), + ('driver_date', ctypes.c_char * 64), +] + +amdsmi_driver_info_t = struct_c__SA_amdsmi_driver_info_t class struct_c__SA_amdsmi_board_info_t(Structure): pass @@ -1613,9 +1623,9 @@ amdsmi_get_gpu_device_bdf.argtypes = [amdsmi_processor_handle, ctypes.POINTER(un amdsmi_get_gpu_device_uuid = _libraries['libamd_smi.so'].amdsmi_get_gpu_device_uuid amdsmi_get_gpu_device_uuid.restype = amdsmi_status_t amdsmi_get_gpu_device_uuid.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_char)] -amdsmi_get_gpu_driver_version = _libraries['libamd_smi.so'].amdsmi_get_gpu_driver_version -amdsmi_get_gpu_driver_version.restype = amdsmi_status_t -amdsmi_get_gpu_driver_version.argtypes = [amdsmi_processor_handle, ctypes.POINTER(ctypes.c_int32), ctypes.POINTER(ctypes.c_char)] +amdsmi_get_gpu_driver_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_driver_info +amdsmi_get_gpu_driver_info.restype = amdsmi_status_t +amdsmi_get_gpu_driver_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_c__SA_amdsmi_driver_info_t)] amdsmi_get_gpu_asic_info = _libraries['libamd_smi.so'].amdsmi_get_gpu_asic_info amdsmi_get_gpu_asic_info.restype = amdsmi_status_t amdsmi_get_gpu_asic_info.argtypes = [amdsmi_processor_handle, ctypes.POINTER(struct_c__SA_amdsmi_asic_info_t)] @@ -1796,10 +1806,10 @@ __all__ = \ 'amdsmi_counter_command_t', 'amdsmi_counter_command_t__enumvalues', 'amdsmi_counter_value_t', 'amdsmi_dev_perf_level_t', 'amdsmi_dev_perf_level_t__enumvalues', - 'amdsmi_engine_usage_t', 'amdsmi_error_count_t', - 'amdsmi_event_group_t', 'amdsmi_event_group_t__enumvalues', - 'amdsmi_event_handle_t', 'amdsmi_event_type_t', - 'amdsmi_event_type_t__enumvalues', + 'amdsmi_driver_info_t', 'amdsmi_engine_usage_t', + 'amdsmi_error_count_t', 'amdsmi_event_group_t', + 'amdsmi_event_group_t__enumvalues', 'amdsmi_event_handle_t', + 'amdsmi_event_type_t', 'amdsmi_event_type_t__enumvalues', 'amdsmi_evt_notification_data_t', 'amdsmi_evt_notification_type_t', 'amdsmi_evt_notification_type_t__enumvalues', 'amdsmi_freq_ind_t', @@ -1816,7 +1826,7 @@ __all__ = \ 'amdsmi_get_gpu_compute_process_info', 'amdsmi_get_gpu_compute_process_info_by_pid', 'amdsmi_get_gpu_device_bdf', 'amdsmi_get_gpu_device_uuid', - 'amdsmi_get_gpu_driver_version', 'amdsmi_get_gpu_ecc_count', + 'amdsmi_get_gpu_driver_info', 'amdsmi_get_gpu_ecc_count', 'amdsmi_get_gpu_ecc_enabled', 'amdsmi_get_gpu_ecc_status', 'amdsmi_get_gpu_event_notification', 'amdsmi_get_gpu_fan_rpms', 'amdsmi_get_gpu_fan_speed', 'amdsmi_get_gpu_fan_speed_max', @@ -1910,6 +1920,7 @@ __all__ = \ 'struct_c__SA_amdsmi_board_info_t', 'struct_c__SA_amdsmi_clk_info_t', 'struct_c__SA_amdsmi_counter_value_t', + 'struct_c__SA_amdsmi_driver_info_t', 'struct_c__SA_amdsmi_engine_usage_t', 'struct_c__SA_amdsmi_error_count_t', 'struct_c__SA_amdsmi_evt_notification_data_t', diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 0e59fcd964..cecd4ad53e 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1444,11 +1444,11 @@ amdsmi_get_power_info(amdsmi_processor_handle processor_handle, amdsmi_power_inf return status; } -amdsmi_status_t -amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *length, char *version) { +amdsmi_status_t amdsmi_get_gpu_driver_info(amdsmi_processor_handle processor_handle, + amdsmi_driver_info_t *info) { AMDSMI_CHECK_INIT(); - if (length == nullptr || version == nullptr) { + if (info == nullptr) { return AMDSMI_STATUS_INVAL; } amdsmi_status_t status = AMDSMI_STATUS_SUCCESS; @@ -1457,11 +1457,17 @@ amdsmi_get_gpu_driver_version(amdsmi_processor_handle processor_handle, int *len if (r != AMDSMI_STATUS_SUCCESS) return r; - status = smi_amdgpu_get_driver_version(gpu_device, length, version); - + int length = AMDSMI_MAX_STRING_LENGTH; + status = smi_amdgpu_get_driver_version(gpu_device, + &length, info->driver_version); + std::string driver_date; + status = gpu_device->amdgpu_query_driver_date(driver_date); + if (status != AMDSMI_STATUS_SUCCESS) return r; + strncpy(info->driver_date, driver_date.c_str(), AMDSMI_MAX_STRING_LENGTH-1); return status; } + amdsmi_status_t amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_handle, unsigned int *uuid_length, char *uuid) { AMDSMI_CHECK_INIT(); diff --git a/projects/amdsmi/src/amd_smi/amd_smi_drm.cc b/projects/amdsmi/src/amd_smi/amd_smi_drm.cc index bf626a9641..9f24920377 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_drm.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_drm.cc @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -99,22 +98,19 @@ amdsmi_status_t AMDSmiDrm::init() { return status; } - using drmGetVersionType = drmVersionPtr (*)(int); // drmGetVersion - using drmFreeVersionType = void (*)(drmVersionPtr); // drmFreeVersion using drmGetDeviceType = int(*)(int, drmDevicePtr*); // drmGetDevice using drmFreeDeviceType = void(*)(drmDevicePtr*); // drmFreeDevice - drmGetVersionType drm_get_version = nullptr; - drmFreeVersionType drm_free_version = nullptr; - drmGetDeviceType drm_get_device = nullptr; drmFreeDeviceType drm_free_device = nullptr; + drm_get_version_ = nullptr; + drm_free_version_ = nullptr; - status = lib_loader_.load_symbol(&drm_get_version, "drmGetVersion"); + status = lib_loader_.load_symbol(&drm_get_version_, "drmGetVersion"); if (status != AMDSMI_STATUS_SUCCESS) { return status; } - status = lib_loader_.load_symbol(&drm_free_version, "drmFreeVersion"); + status = lib_loader_.load_symbol(&drm_free_version_, "drmFreeVersion"); if (status != AMDSMI_STATUS_SUCCESS) { return status; } @@ -155,7 +151,7 @@ amdsmi_status_t AMDSmiDrm::init() { amdsmi_bdf_t bdf; if (fd >= 0) { auto version = drm_version_ptr( - drm_get_version(fd), drm_free_version); + drm_get_version_(fd), drm_free_version_); if (strcmp("amdgpu", version->name)) { // only amdgpu close(fd); fd = -1; @@ -201,6 +197,18 @@ amdsmi_status_t AMDSmiDrm::cleanup() { return AMDSMI_STATUS_SUCCESS; } +amdsmi_status_t AMDSmiDrm::amdgpu_query_driver_date(int fd, std::string& driver_date) { + // RAII handler + using drm_version_ptr = std::unique_ptr; + std::lock_guard guard(drm_mutex_); + auto version = drm_version_ptr( + drm_get_version_(fd), drm_free_version_); + if (version == nullptr) return AMDSMI_STATUS_DRM_ERROR; + driver_date = version->date; + return AMDSMI_STATUS_SUCCESS; +} + amdsmi_status_t AMDSmiDrm::amdgpu_query_info(int fd, unsigned info_id, unsigned size, void *value) { if (drm_cmd_write_ == nullptr) return AMDSMI_STATUS_NOT_SUPPORTED; diff --git a/projects/amdsmi/src/amd_smi/amd_smi_gpu_device.cc b/projects/amdsmi/src/amd_smi/amd_smi_gpu_device.cc index 1dab7a267b..9d4a243b6f 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi_gpu_device.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi_gpu_device.cc @@ -105,6 +105,15 @@ amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_info(unsigned info_id, return drm_.amdgpu_query_info(fd, info_id, size, value); } +amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_driver_date(std::string& date) const { + amdsmi_status_t ret; + uint32_t fd = 0; + ret = drm_.get_drm_fd_by_index(gpu_id_, &fd); + if (ret != AMDSMI_STATUS_SUCCESS) return AMDSMI_STATUS_NOT_SUPPORTED; + + return drm_.amdgpu_query_driver_date(fd, date); +} + amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_hw_ip(unsigned info_id, unsigned hw_ip_type, unsigned size, void *value) const { amdsmi_status_t ret;