From 05c7aa953fcddc27b7467c6dba8f9ce88cb4cb4d Mon Sep 17 00:00:00 2001 From: Divya Shikre Date: Wed, 24 Jun 2020 15:22:46 -0400 Subject: [PATCH] OAM: Implement get_sensors_info() Signed-off-by: Divya Shikre Change-Id: Ia2c6e18f463c0f97530ca8ad07d249e6f2116534 [ROCm/amdsmi commit: e21232f05945ea54f538b7272036e4857f61f478] --- projects/amdsmi/oam/example/oam_example.c | 93 +++++++++++++---- projects/amdsmi/oam/include/oam/amd_oam.h | 2 + projects/amdsmi/oam/include/oam/oam_mapi.h | 10 +- projects/amdsmi/oam/src/amd_oam.cc | 113 ++++++++++++++++----- 4 files changed, 166 insertions(+), 52 deletions(-) diff --git a/projects/amdsmi/oam/example/oam_example.c b/projects/amdsmi/oam/example/oam_example.c index c68b4c9d9f..232fd205af 100644 --- a/projects/amdsmi/oam/example/oam_example.c +++ b/projects/amdsmi/oam/example/oam_example.c @@ -11,8 +11,29 @@ const oam_ops_t amd_oam_ops = { .get_pci_properties = amdoam_get_pci_properties, .get_sensors_count = amdoam_get_sensors_count, .get_error_description = amdoam_get_error_description, + .get_sensors_info = amdoam_get_sensors_info, }; +static int get_sensor_info(uint32_t device_id, oam_sensor_type_t type, + uint32_t num_sensors, char unit[]) { + uint32_t j; + oam_sensor_info_t *sensor_info = calloc(num_sensors, + sizeof(oam_sensor_info_t)); + if (!sensor_info) { + printf("Allocating power_info failed\n"); + return -1; + } + amd_oam_ops.get_sensors_info(device_id, type, num_sensors, sensor_info); + for ( j = 0; j < num_sensors ; j++) { + printf("\tSensor Name : %s \n", sensor_info[j].sensor_name); + printf("\tSensor Type : %d \n", sensor_info[j].sensor_type); + printf("\tSensor Value : %ld %s\n", sensor_info[j].value, unit); + } + free(sensor_info); + printf("\t**************************************\n"); + return 0; +} + int main() { uint32_t dev_cnt = 0; @@ -33,44 +54,72 @@ int main() printf("%d AMD devices are discovered\n", dev_cnt); if (!dev_cnt) { printf("No devices are found.\n"); - return -1; + return amd_oam_ops.free(); } devs_prop = calloc(dev_cnt, sizeof(oam_dev_properties_t)); if (!devs_prop) { printf("Allocating dev_prop failed\n"); - return -1; + return amd_oam_ops.free(); } amd_oam_ops.get_dev_properties(dev_cnt, devs_prop); for (i = 0; i < dev_cnt; i++) { printf("Device %d:\n", i); - printf(" device id %d\n", devs_prop[i].device_id); - printf(" device_vendor %s\n", devs_prop[i].device_vendor); - printf(" device_name %s\n", devs_prop[i].device_name); - printf(" sku_name %s\n", devs_prop[i].sku_name); - printf(" board_name %s\n", devs_prop[i].board_name); - printf(" board_revision %s\n", devs_prop[i].board_revision); - printf(" board_serial_number %s\n", - devs_prop[i].board_serial_number); + printf("\tdevice id %d\n", devs_prop[i].device_id); + printf("\tdevice_vendor %s\n", devs_prop[i].device_vendor); + printf("\tdevice_name %s\n", devs_prop[i].device_name); + printf("\tsku_name %s\n", devs_prop[i].sku_name); + printf("\tboard_name %s\n", devs_prop[i].board_name); + printf("\tboard_revision %s\n", devs_prop[i].board_revision); + printf("\tboard_serial_number %s\n", + devs_prop[i].board_serial_number); - if (!amd_oam_ops.get_pci_properties(devs_prop[i].device_id, &pci_info)){ - printf(" PCI Domain : 0x%d \n", pci_info.domain); - printf(" PCI bus : 0x%d \n", pci_info.bus); - printf(" PCI device : 0x%d \n", pci_info.device); - printf(" PCI function : 0x%d \n", pci_info.function); - } - if(!amd_oam_ops.get_sensors_count(devs_prop[i].device_id, &sensor_count)) { - printf(" Temperature Sensors : %d \n", sensor_count.num_temperature_sensors); - printf(" Power Sensors : %d \n", sensor_count.num_power_sensors); - printf(" Voltage Sensors : %d \n", sensor_count.num_voltage_sensors); - printf(" Current Sensors : %d \n", sensor_count.num_current_sensors); - printf(" Fan Sensors : %d \n", sensor_count.num_fans); + if (!amd_oam_ops.get_pci_properties( + devs_prop[i].device_id, &pci_info)) { + printf("\tPCI domain : 0x%d \n", pci_info.domain); + printf("\tPCI bus : 0x%d \n", pci_info.bus); + printf("\tPCI device : 0x%d \n", pci_info.device); + printf("\tPCI function : 0x%d \n", pci_info.function); } + + printf("\t**************************************\n"); + if (amd_oam_ops.get_sensors_count( + devs_prop[i].device_id, &sensor_count)) + continue; + printf("\tNumber of Power Sensors : %d \n", + sensor_count.num_power_sensors); + if (get_sensor_info(devs_prop[i].device_id,OAM_SENSOR_TYPE_POWER, + sensor_count.num_power_sensors, "uW")) + goto failure; + + printf("\tNumber of Voltage Sensors : %d \n", + sensor_count.num_voltage_sensors); + if (get_sensor_info(devs_prop[i].device_id, OAM_SENSOR_TYPE_VOLTAGE, + sensor_count.num_voltage_sensors, "mV")) + goto failure; + + printf("\tNumber of Current Sensors : %d \n", + sensor_count.num_current_sensors); + if (get_sensor_info(devs_prop[i].device_id, OAM_SENSOR_TYPE_CURRENT, + sensor_count.num_current_sensors, "A")) + goto failure; + + printf("\tNumber of Temperature Sensors : %d \n", + sensor_count.num_temperature_sensors); + if (get_sensor_info(devs_prop[i].device_id, OAM_SENSOR_TYPE_TEMP, + sensor_count.num_temperature_sensors, "mC")) + goto failure; + + printf("\tNumber of Fan Sensors : %d \n", sensor_count.num_fans); + if (get_sensor_info(devs_prop[i].device_id, OAM_SENSOR_TYPE_FAN_SPEED, + sensor_count.num_fans, "rpm")) + goto failure; } amd_oam_ops.get_error_description(1, &string); printf("error code 1: %s\n", string); +failure: free(devs_prop); amd_oam_ops.free(); diff --git a/projects/amdsmi/oam/include/oam/amd_oam.h b/projects/amdsmi/oam/include/oam/amd_oam.h index b25e2b7e7d..5c0a778200 100755 --- a/projects/amdsmi/oam/include/oam/amd_oam.h +++ b/projects/amdsmi/oam/include/oam/amd_oam.h @@ -60,6 +60,8 @@ int amdoam_get_pci_properties(uint32_t device_id, oam_pci_info_t *pci_info); int amdoam_get_sensors_count(uint32_t device_id, oam_sensor_count_t *sensor_count); int amdoam_get_error_description(int code, const char **description); +int amdoam_get_sensors_info(uint32_t device_id, oam_sensor_type_t type, + uint32_t num_sensors, oam_sensor_info_t sensor_info[]); #ifdef __cplusplus } diff --git a/projects/amdsmi/oam/include/oam/oam_mapi.h b/projects/amdsmi/oam/include/oam/oam_mapi.h index 2a3c6172ac..2500b65bb4 100755 --- a/projects/amdsmi/oam/include/oam/oam_mapi.h +++ b/projects/amdsmi/oam/include/oam/oam_mapi.h @@ -122,7 +122,7 @@ typedef enum oam_sensor_type { OAM_SENSOR_TYPE_CURRENT, OAM_SENSOR_TYPE_TEMP, OAM_SENSOR_TYPE_FAN_SPEED, - OAM_SENSOR_TYPE_UNKNOWN = 0xFF + OAM_SENSOR_TYPE_UNKNOWN } oam_sensor_type_t; /** @@ -221,15 +221,13 @@ typedef enum oam_dev_mode { /** * \struct oam_sensor_info_t * \brief Sensor information - * \details Device handle obtained using open call - * The same handle is used by all the APIs which are used to perform - * specific operation on that device. + * \details Structure to store various info of sensors. */ typedef struct oam_sensor_info { char sensor_name[OAM_SENSOR_NAME_MAX]; oam_sensor_type_t sensor_type; oam_sensor_scale_t scale; - int32_t value; + int64_t value; } oam_sensor_info_t; /** @@ -496,7 +494,7 @@ typedef struct oam_ops { /*!< * To read various sensor values for a given sensor type */ - int (*get_sensors_info)(oam_dev_handle_t *handle, + int (*get_sensors_info)(uint32_t device_id, oam_sensor_type_t type, uint32_t num_sensors, oam_sensor_info_t sensor_info[]); diff --git a/projects/amdsmi/oam/src/amd_oam.cc b/projects/amdsmi/oam/src/amd_oam.cc index 26c0d79a22..60778492a1 100755 --- a/projects/amdsmi/oam/src/amd_oam.cc +++ b/projects/amdsmi/oam/src/amd_oam.cc @@ -178,17 +178,16 @@ CATCH return AMDOAM_STATUS_SUCCESS; } -static int get_num_sensors(std::string hwmon_path, std::string fn_reg_ex, - uint32_t *sensor_max) { - *sensor_max = 0; - fn_reg_ex = "\\b" + fn_reg_ex + "([0-9]+)([^ ]*)"; +static int get_num_sensors(std::string hwmon_path, std::string fn_reg) { + uint32_t sensor_max = 0; + std::string fn_reg_ex = "\\b" + fn_reg + "([0-9]+)([^ ]*)"; std::string fn; std::smatch m; uint32_t temp = 0; + std::string s1("in"); std::regex re(fn_reg_ex); auto hwmon_dir = opendir(hwmon_path.c_str()); - if (hwmon_dir == nullptr) - return 0; + assert(hwmon_dir != nullptr); auto dentry = readdir(hwmon_dir); while (dentry != nullptr) { fn = dentry->d_name; @@ -198,37 +197,103 @@ static int get_num_sensors(std::string hwmon_path, std::string fn_reg_ex, std::regex("[^0-9]*([0-9]+).*"), std::string("$1")); temp = stoi(output); - if (temp > *sensor_max) { - *sensor_max = temp; - } + + if (s1.compare(fn_reg) == 0) + ++temp; + if (temp > sensor_max) + sensor_max = temp; } dentry = readdir(hwmon_dir); } - if (closedir(hwmon_dir)) { - return -errno; - } - return 0; + closedir(hwmon_dir); + return sensor_max; } + int amdoam_get_sensors_count(uint32_t device_id, oam_sensor_count_t *sensor_count) { uint32_t dv_ind = device_id; - uint32_t num_sensors = 0; TRY + if (sensor_count == nullptr) + return -AMDOAM_STATUS_INVALID_ARGS; GET_DEV_FROM_INDX + assert(dev->monitor() != nullptr); std::string hwmon_path = dev->monitor()->path(); - get_num_sensors(hwmon_path, "temp", &num_sensors); - sensor_count->num_temperature_sensors = num_sensors; - get_num_sensors(hwmon_path, "fan", &num_sensors); - sensor_count->num_fans = num_sensors; - get_num_sensors(hwmon_path, "in", &num_sensors); - sensor_count->num_voltage_sensors = (num_sensors+1); - get_num_sensors(hwmon_path, "power", &num_sensors); - sensor_count->num_power_sensors = num_sensors; - get_num_sensors(hwmon_path, "current", &num_sensors); - sensor_count->num_current_sensors = num_sensors; + sensor_count->num_temperature_sensors = get_num_sensors(hwmon_path, "temp"); + sensor_count->num_fans = get_num_sensors(hwmon_path, "fan"); + sensor_count->num_voltage_sensors = get_num_sensors(hwmon_path, "in"); + sensor_count->num_power_sensors = get_num_sensors(hwmon_path, "power"); + sensor_count->num_current_sensors = get_num_sensors(hwmon_path, "current"); + CATCH + + return AMDOAM_STATUS_SUCCESS; +} + +int amdoam_get_sensors_info(uint32_t device_id, oam_sensor_type_t type, + uint32_t num_sensors, oam_sensor_info_t sensor_info[]) { + uint32_t dv_ind = device_id; + std::string val_str; + uint32_t i; + rsmi_status_t status; + + TRY + if ((sensor_info == nullptr) || (type >= OAM_SENSOR_TYPE_UNKNOWN)) + return -AMDOAM_STATUS_INVALID_ARGS; + GET_DEV_FROM_INDX + assert(dev->monitor() != nullptr); + switch (type) { + case OAM_SENSOR_TYPE_POWER: + for (i = 0; i < num_sensors; i++) { + snprintf(sensor_info[i].sensor_name, OAM_SENSOR_NAME_MAX, + "POWER_SENSOR_%d", i+1); + sensor_info[i].sensor_type = type; + status = rsmi_dev_power_ave_get(device_id, i, + reinterpret_cast(&sensor_info[i].value)); + if (status != RSMI_STATUS_SUCCESS) + return rsmi_status_to_amdoam_errorcode(status); + } + break; + + case OAM_SENSOR_TYPE_VOLTAGE: + for (i = 0; i < num_sensors; i++) { + snprintf(sensor_info[i].sensor_name, OAM_SENSOR_NAME_MAX, + "VOLTAGE_SENSOR_%d", i); + sensor_info[i].sensor_type = type; + status = rsmi_dev_volt_metric_get(device_id, RSMI_VOLT_TYPE_VDDGFX, + RSMI_VOLT_CURRENT, &sensor_info[i].value); + if (status != RSMI_STATUS_SUCCESS) + return rsmi_status_to_amdoam_errorcode(status); + } + break; + + case OAM_SENSOR_TYPE_TEMP: + for (i = 0; i < num_sensors; i++) { + snprintf(sensor_info[i].sensor_name, OAM_SENSOR_NAME_MAX, + "TEMP_SENSOR_%d", i+1); + sensor_info[i].sensor_type = type; + status = rsmi_dev_temp_metric_get(device_id, i, RSMI_TEMP_CURRENT, + &sensor_info[i].value); + if (status != RSMI_STATUS_SUCCESS) + return rsmi_status_to_amdoam_errorcode(status); + } + break; + + case OAM_SENSOR_TYPE_FAN_SPEED: + for (i = 0; i < num_sensors; i++) { + snprintf(sensor_info[i].sensor_name, OAM_SENSOR_NAME_MAX, + "FAN_SENSOR_%d", i+1); + sensor_info[i].sensor_type = type; + status = rsmi_dev_fan_speed_get(device_id, i, &sensor_info[i].value); + if (status != RSMI_STATUS_SUCCESS) + return rsmi_status_to_amdoam_errorcode(status); + } + break; + + default: + return -AMDOAM_STATUS_NOT_SUPPORTED; + } CATCH return AMDOAM_STATUS_SUCCESS;