From 528161560db21f15345a199695580ab2600f1bc3 Mon Sep 17 00:00:00 2001 From: "Bill(Shuzhou) Liu" Date: Tue, 3 Oct 2023 11:11:56 -0500 Subject: [PATCH] Read PCIe slot type from sysfs Read the PCIe slot type from sysfs instead of libdrm. Change-Id: I9392b9e18a209ac7332f6902bcafb3b6062c86c1 [ROCm/amdsmi commit: 656f12e0f3905b9c79a16c6de5033a4d7ae724eb] --- .../rocm_smi/include/rocm_smi/rocm_smi.h | 33 +++++++++++++++++ .../include/rocm_smi/rocm_smi_device.h | 4 +++ .../include/rocm_smi/rocm_smi_utils.h | 3 ++ projects/amdsmi/rocm_smi/src/rocm_smi.cc | 23 ++++++++++++ .../amdsmi/rocm_smi/src/rocm_smi_device.cc | 31 ++++++++++++++++ projects/amdsmi/rocm_smi/src/rocm_smi_main.cc | 1 + projects/amdsmi/src/amd_smi/amd_smi.cc | 36 +++++++------------ 7 files changed, 107 insertions(+), 24 deletions(-) diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h index 6f8cb475ac..31064f3cc9 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi.h @@ -625,6 +625,19 @@ typedef enum { typedef rsmi_freq_ind_t rsmi_freq_ind; /// \endcond +/** + * @brief The values of this enum are used as PCIe slot type. + */ +typedef enum { + RSMI_PCIE_SLOT_PCIE = 0, + RSMI_PCIE_SLOT_CEM = 1, + RSMI_PCIE_SLOT_OAM = 2, + RSMI_PCIE_SLOT_UNKNOWN = 3 //!< An unknown +} rsmi_pcie_slot_type_t; +/// \cond Ignore in docs. +typedef rsmi_pcie_slot_type_t rsmi_pcie_slot_type; +/// \endcond + /** * @brief The values of this enum are used to identify the various firmware @@ -1391,6 +1404,26 @@ rsmi_status_t rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name, rsmi_status_t rsmi_dev_vram_vendor_get(uint32_t dv_ind, char *brand, uint32_t len); + +/** + * @brief Get the PCIe slot type of a gpu device. + * + * @details Given a device index @p dv_ind, a pointer to a caller provided + * char buffer @p type, this function will write the PCIe slot type of the + * device to @p type. + * + * + * @param[in] dv_ind a device index + * + * @param[inout] type a pointer to a caller provided buffer to which the + * type info will be written + * + * @retval ::RSMI_STATUS_SUCCESS is returned upon successful call. + * + */ +rsmi_status_t rsmi_dev_pcie_slot_type_get(uint32_t dv_ind, + rsmi_pcie_slot_type_t* type); + /** * @brief Get the serial number string for a device * diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h index e9a61af972..8640bae9c1 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_device.h @@ -105,6 +105,7 @@ enum DevInfoTypes { kDevDevRevID, kDevDevProdName, kDevDevProdNum, + kDevBoardInfo, kDevVendorID, kDevSubSysDevID, kDevSubSysVendorID, @@ -200,6 +201,9 @@ class Device { int readDevInfo(DevInfoTypes type, std::vector *retVec); int readDevInfo(DevInfoTypes type, std::size_t b_size, void *p_binary_data); + // Get the property from a file which may contain multiple properties. + int readDevInfo(DevInfoTypes type, const std::string& property, + std::string& value); int writeDevInfo(DevInfoTypes type, uint64_t val); int writeDevInfo(DevInfoTypes type, std::string val); diff --git a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_utils.h b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_utils.h index f66eedf314..174ae3e988 100755 --- a/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_utils.h +++ b/projects/amdsmi/rocm_smi/include/rocm_smi/rocm_smi_utils.h @@ -269,6 +269,9 @@ class ScopedAcquire { // In VM environment, the /proc/cpuinfo set hypervisor flag by default bool is_vm_guest(); +// trim a string +std::string trim(const std::string &s); + } // namespace smi } // namespace amd diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi.cc b/projects/amdsmi/rocm_smi/src/rocm_smi.cc index 79c703bc31..10cca04b8d 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi.cc @@ -910,6 +910,29 @@ rsmi_dev_vendor_id_get(uint32_t dv_ind, uint16_t *id) { return get_id(dv_ind, amd::smi::kDevVendorID, id); } +rsmi_status_t +rsmi_dev_pcie_slot_type_get(uint32_t dv_ind, rsmi_pcie_slot_type_t* type) { + TRY + + std::ostringstream ss; + ss << __PRETTY_FUNCTION__ << "| ======= start ======="; + LOG_TRACE(ss); + CHK_SUPPORT_NAME_ONLY(type) + DEVICE_MUTEX + + std::string value; + int ret = dev->readDevInfo(amd::smi::kDevBoardInfo, "type", value); + if (ret != 0) return RSMI_STATUS_NOT_SUPPORTED; + + *type = RSMI_PCIE_SLOT_PCIE; + if (value.compare("oam") == 0) *type=RSMI_PCIE_SLOT_OAM; + else if (value.compare("cem") == 0 ) *type=RSMI_PCIE_SLOT_CEM; + else if (value.compare("unknown") == 0 ) *type=RSMI_PCIE_SLOT_UNKNOWN; + return RSMI_STATUS_SUCCESS; + + CATCH +} + rsmi_status_t rsmi_dev_subsystem_vendor_id_get(uint32_t dv_ind, uint16_t *id) { std::ostringstream ss; diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc b/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc index 1310b27956..a1a45795e2 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi_device.cc @@ -87,6 +87,7 @@ static const char *kDevDevProdNumFName = "product_number"; static const char *kDevDevIDFName = "device"; static const char *kDevDevRevIDFName = "revision"; static const char *kDevVendorIDFName = "vendor"; +static const char *kDevBoardInfoFName = "board_info"; static const char *kDevSubSysDevIDFName = "subsystem_device"; static const char *kDevSubSysVendorIDFName = "subsystem_vendor"; static const char *kDevOverDriveLevelFName = "pp_sclk_od"; @@ -238,6 +239,7 @@ static const std::map kDevAttribNameMap = { {kDevPerfLevel, kDevPerfLevelFName}, {kDevOverDriveLevel, kDevOverDriveLevelFName}, {kDevMemOverDriveLevel, kDevMemOverDriveLevelFName}, + {kDevBoardInfo, kDevBoardInfoFName}, {kDevDevProdName, kDevDevProdNameFName}, {kDevDevProdNum, kDevDevProdNumFName}, {kDevDevID, kDevDevIDFName}, @@ -388,6 +390,7 @@ static const std::map kDevFuncDependsMap = { {"rsmi_dev_name_get", {{kDevVendorIDFName, kDevDevIDFName}, {}}}, {"rsmi_dev_sku_get", {{kDevDevProdNumFName}, {}}}, + {"rsmi_dev_pcie_slot_type_get", {{kDevBoardInfoFName}, {}}}, {"rsmi_dev_brand_get", {{kDevVendorIDFName, kDevVBiosVerFName}, {}}}, {"rsmi_dev_vendor_name_get", {{kDevVendorIDFName}, {}}}, @@ -1003,6 +1006,34 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) { return 0; } +// Read a property from a file which may contain multiple properties +int Device::readDevInfo(DevInfoTypes type, const std::string& property, + std::string& value) { + std::vector val; + int ret = 0; + switch (type) { + case kDevBoardInfo: + ret = readDevInfoMultiLineStr(type, &val); + break; + default: + return EINVAL; + } + if (ret != 0) return ret; + + // Find the property from the file + for (unsigned int i = 0; i < val.size(); i++) { + auto pos = val[i].find(":"); // delimiter + if (pos == std::string::npos) continue; + auto name = trim(val[i].substr(0, pos)); + if (name != property) continue; + value = trim(val[i].substr(pos+1)); + return 0; + } + + + return EINVAL; +} + int Device::readDevInfo(DevInfoTypes type, std::vector *val) { assert(val != nullptr); diff --git a/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc b/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc index 9089e9093d..2e5b322f28 100755 --- a/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc +++ b/projects/amdsmi/rocm_smi/src/rocm_smi_main.cc @@ -86,6 +86,7 @@ amd::smi::RocmSMI::devInfoTypesStrings = { {amd::smi::kDevDevID, amdSMI + "kDevDevID"}, {amd::smi::kDevDevRevID, amdSMI + "kDevDevRevID"}, {amd::smi::kDevDevProdName, amdSMI + "kDevDevProdName"}, + {amd::smi::kDevBoardInfo, amdSMI + "kDevBoardInfo"}, {amd::smi::kDevDevProdNum, amdSMI + "kDevDevProdNum"}, {amd::smi::kDevVendorID, amdSMI + "kDevVendorID"}, {amd::smi::kDevSubSysDevID, amdSMI + "kDevSubSysDevID"}, diff --git a/projects/amdsmi/src/amd_smi/amd_smi.cc b/projects/amdsmi/src/amd_smi/amd_smi.cc index 20306ebf51..7040860e06 100644 --- a/projects/amdsmi/src/amd_smi/amd_smi.cc +++ b/projects/amdsmi/src/amd_smi/amd_smi.cc @@ -1830,22 +1830,14 @@ amdsmi_get_pcie_link_status(amdsmi_processor_handle processor_handle, amdsmi_pci // default to PCIe info->pcie_slot_type = AMDSMI_SLOT_TYPE__PCIE; - amd::smi::AMDSmiGPUDevice* gpu_device = nullptr; - status = get_gpu_device_from_handle( - processor_handle, &gpu_device); - if (status == AMDSMI_STATUS_SUCCESS - && gpu_device->check_if_drm_is_supported()) { - struct drm_amdgpu_info_device dev_info = {}; - status = gpu_device->amdgpu_query_info(AMDGPU_INFO_DEV_INFO, - sizeof(struct drm_amdgpu_memory_info), &dev_info); - // bits [16:17] in ids_flags field as slot type - if (status == AMDSMI_STATUS_SUCCESS) { - // two bits starts with index 16 - info->pcie_slot_type = static_cast((dev_info.ids_flags >> 16) & 0x03); - } + rsmi_pcie_slot_type_t slot_type; + status = rsmi_wrapper(rsmi_dev_pcie_slot_type_get, + processor_handle, &slot_type); + if (status == AMDSMI_STATUS_SUCCESS) { + info->pcie_slot_type = static_cast(slot_type); } - return status; + return AMDSMI_STATUS_SUCCESS; } amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_handle, amdsmi_pcie_info_t *info) { @@ -1921,18 +1913,14 @@ amdsmi_status_t amdsmi_get_pcie_link_caps(amdsmi_processor_handle processor_hand // default to PCIe info->pcie_slot_type = AMDSMI_SLOT_TYPE__PCIE; - if (gpu_device->check_if_drm_is_supported()) { - struct drm_amdgpu_info_device dev_info = {}; - status = gpu_device->amdgpu_query_info(AMDGPU_INFO_DEV_INFO, - sizeof(struct drm_amdgpu_memory_info), &dev_info); - // bits [16:17] in ids_flags field as slot type - if (status == AMDSMI_STATUS_SUCCESS) { - // two bits starts with index 16 - info->pcie_slot_type = static_cast((dev_info.ids_flags >> 16) & 0x03); - } + rsmi_pcie_slot_type_t slot_type; + status = rsmi_wrapper(rsmi_dev_pcie_slot_type_get, + processor_handle, &slot_type); + if (status == AMDSMI_STATUS_SUCCESS) { + info->pcie_slot_type = static_cast(slot_type); } - return status; + return AMDSMI_STATUS_SUCCESS; } amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf,