Added new id and id name string look up functions

Also, updated docs with typo corrections and a new section
This commit is contained in:
Chris Freehill
2019-03-15 16:21:37 -05:00
parent 58d5ff7509
commit cbdfac7bdc
12 changed files with 599 additions and 82 deletions
+176 -59
View File
@@ -387,17 +387,6 @@ static rsmi_status_t get_power_mon_value(amd::smi::PowerMonTypes type,
return errno_to_rsmi_status(ret);
}
static rsmi_status_t get_dev_mon_value_str(amd::smi::MonitorTypes type,
uint32_t dv_ind, int32_t sensor_ind, std::string *val_str) {
GET_DEV_FROM_INDX
assert(dev->monitor() != nullptr);
int ret = dev->monitor()->readMonitor(type, sensor_ind, val_str);
return errno_to_rsmi_status(ret);
}
static rsmi_status_t get_dev_value_vec(amd::smi::DevInfoTypes type,
uint32_t dv_ind, std::vector<std::string> *val_vec) {
GET_DEV_FROM_INDX
@@ -509,11 +498,11 @@ rsmi_dev_pci_id_get(uint32_t dv_ind, uint64_t *bdfid) {
CATCH
}
rsmi_status_t
rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id) {
static rsmi_status_t
get_id(uint32_t dv_ind, amd::smi::DevInfoTypes typ, uint16_t *id) {
TRY
std::string val_str;
rsmi_status_t ret = get_dev_value_str(amd::smi::kDevDevID, dv_ind, &val_str);
rsmi_status_t ret = get_dev_value_str(typ, dv_ind, &val_str);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
@@ -527,6 +516,26 @@ rsmi_dev_id_get(uint32_t dv_ind, uint64_t *id) {
CATCH
}
rsmi_status_t
rsmi_dev_id_get(uint32_t dv_ind, uint16_t *id) {
return get_id(dv_ind, amd::smi::kDevDevID, id);
}
rsmi_status_t
rsmi_dev_subsystem_id_get(uint32_t dv_ind, uint16_t *id) {
return get_id(dv_ind, amd::smi::kDevSubSysDevID, id);
}
rsmi_status_t
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_subsystem_vendor_id_get(uint32_t dv_ind, uint16_t *id) {
return get_id(dv_ind, amd::smi::kDevSubSysVendorID, id);
}
rsmi_status_t
rsmi_dev_perf_level_get(uint32_t dv_ind, rsmi_dev_perf_level_t *perf) {
TRY
@@ -957,15 +966,74 @@ static std::vector<std::string> pci_name_files = {
"/var/lib/pciutils/pci.ids"
};
enum eNameStrType {
NAME_STR_VENDOR = 0,
NAME_STR_DEVICE,
NAME_STR_SUBSYS
};
static std::string
get_id_name_str_from_line(uint64_t id, std::string ln,
std::istringstream *ln_str) {
std::string token1;
std::string ret_str;
assert(ln_str != nullptr);
*ln_str >> token1;
if (std::stoul(token1, nullptr, 16) == id) {
int64_t pos = ln_str->tellg();
pos = ln.find_first_not_of("\t ", pos);
ret_str = ln.substr(pos);
}
return ret_str;
}
// Parse pci.ids files. Comment lines have # in first column. Otherwise,
// Syntax:
// vendor vendor_name
// device device_name <-- single tab
// subvendor subdevice subsystem_name <-- two tabs
static std::string get_dev_name_from_id(uint64_t id) {
static rsmi_status_t get_dev_name_from_id(uint32_t dv_ind, char *name,
size_t len, eNameStrType typ) {
std::string ln;
std::string token1;
std::string description;
rsmi_status_t ret;
uint16_t device_id;
uint16_t vendor_id;
uint16_t subsys_vend_id;
uint16_t subsys_id;
bool found_device_vendor = false;
std::string val_str;
assert(name != nullptr);
assert(len > 0);
name[0] = '\0';
ret = rsmi_dev_vendor_id_get(dv_ind, &vendor_id);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
if (typ != NAME_STR_VENDOR) {
ret = rsmi_dev_id_get(dv_ind, &device_id);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
if (typ != NAME_STR_DEVICE) {
ret = rsmi_dev_subsystem_vendor_id_get(dv_ind, &subsys_vend_id);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
ret = rsmi_dev_subsystem_id_get(dv_ind, &subsys_id);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
}
}
for (auto fl : pci_name_files) {
std::ifstream id_file_strm(fl);
@@ -973,71 +1041,120 @@ static std::string get_dev_name_from_id(uint64_t id) {
while (std::getline(id_file_strm, ln)) {
std::istringstream ln_str(ln);
// parse line
if (ln_str.peek() == '#') {
if (ln[0] == '#' || ln.size() == 0) {
continue;
}
if (ln[0] == '\t') {
if (ln[1] == '\t') {
if (ln[2] == '\t') {
// This is a subvendor line
}
} else { // ln[1] != '\t'
// This is a device line
ln_str >> token1;
if (std::stoul(token1, nullptr, 16) == id) {
int64_t pos = ln_str.tellg();
if (found_device_vendor) {
if (ln[1] == '\t') {
// This is a subsystem line
if (typ == NAME_STR_SUBSYS) {
val_str = get_id_name_str_from_line(subsys_vend_id, ln, &ln_str);
pos = ln.find_first_not_of("\t ", pos);
description = ln.substr(pos);
return description;
if (val_str.size() > 0) {
// We've chopped the subsys_vend ID, now we need to get the
// subsys description
val_str = get_id_name_str_from_line(subsys_id, ln, &ln_str);
if (val_str.size() > 0) {
break;
} else {
val_str.clear();
}
}
}
} else if (typ == NAME_STR_DEVICE) { // ln[1] != '\t'
// This is a device line
val_str = get_id_name_str_from_line(device_id, ln, &ln_str);
if (val_str.size() > 0) {
break;
}
}
}
} else { // ln[0] != '\t'; Vendor line
if (found_device_vendor) {
// We already found the vendor but didn't find the device or
// subsystem we were looking for, so bail out.
val_str.clear();
return RSMI_STATUS_NOT_FOUND;
}
val_str = get_id_name_str_from_line(vendor_id, ln, &ln_str);
if (val_str.size() > 0) {
if (typ == NAME_STR_VENDOR) {
break;
} else {
val_str.clear();
found_device_vendor = true;
}
}
} else { // ln[0] != '\t'
// This is a vendor line
}
}
}
return description;
}
rsmi_status_t
rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) {
TRY
if (name == nullptr || len == 0) {
return RSMI_STATUS_INVALID_ARGS;
}
std::string val_str;
rsmi_status_t ret;
uint64_t id;
ret = rsmi_dev_id_get(dv_ind, &id);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
val_str = get_dev_name_from_id(id);
if (val_str.size() == 0) {
ret = get_dev_mon_value_str(amd::smi::kMonName, dv_ind, -1, &val_str);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
if (val_str.size() > 0) {
break;
}
}
size_t ln = val_str.copy(name, len);
size_t ct = val_str.copy(name, len);
name[std::min(len - 1, ln)] = '\0';
name[std::min(len - 1, ct)] = '\0';
if (len < val_str.size()) {
return RSMI_STATUS_INSUFFICIENT_SIZE;
}
return RSMI_STATUS_SUCCESS;
}
rsmi_status_t
rsmi_dev_name_get(uint32_t dv_ind, char *name, size_t len) {
rsmi_status_t ret;
TRY
if (name == nullptr || len == 0) {
return RSMI_STATUS_INVALID_ARGS;
}
ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_DEVICE);
if (ret != RSMI_STATUS_SUCCESS) {
return ret;
}
return RSMI_STATUS_SUCCESS;
CATCH
}
rsmi_status_t
rsmi_dev_subsystem_name_get(uint32_t dv_ind, char *name, size_t len) {
rsmi_status_t ret;
TRY
if (name == nullptr || len == 0) {
return RSMI_STATUS_INVALID_ARGS;
}
ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_SUBSYS);
return ret;
CATCH
}
rsmi_status_t
rsmi_dev_vendor_name_get(uint32_t dv_ind, char *name, size_t len) {
rsmi_status_t ret;
TRY
if (name == nullptr || len == 0) {
return RSMI_STATUS_INVALID_ARGS;
}
ret = get_dev_name_from_id(dv_ind, name, len, NAME_STR_VENDOR);
return ret;
CATCH
}
rsmi_status_t
rsmi_dev_pci_bandwidth_get(uint32_t dv_ind, rsmi_pcie_bandwidth_t *b) {
TRY
+12 -7
View File
@@ -62,6 +62,9 @@ namespace smi {
// Sysfs file names
static const char *kDevPerfLevelFName = "power_dpm_force_performance_level";
static const char *kDevDevIDFName = "device";
static const char *kDevVendorIDFName = "vendor";
static const char *kDevSubSysDevIDFName = "subsystem_device";
static const char *kDevSubSysVendorIDFName = "subsystem_vendor";
static const char *kDevOverDriveLevelFName = "pp_sclk_od";
static const char *kDevGPUSClkFName = "pp_dpm_sclk";
static const char *kDevGPUMClkFName = "pp_dpm_mclk";
@@ -96,6 +99,9 @@ static const std::map<DevInfoTypes, const char *> kDevAttribNameMap = {
{kDevPerfLevel, kDevPerfLevelFName},
{kDevOverDriveLevel, kDevOverDriveLevelFName},
{kDevDevID, kDevDevIDFName},
{kDevVendorID, kDevVendorIDFName},
{kDevSubSysDevID, kDevSubSysDevIDFName},
{kDevSubSysVendorID, kDevSubSysVendorIDFName},
{kDevGPUMClk, kDevGPUMClkFName},
{kDevGPUSClk, kDevGPUSClkFName},
{kDevPCIEClk, kDevGPUPCIEClkFname},
@@ -236,10 +242,6 @@ int Device::writeDevInfo(DevInfoTypes type, uint64_t val) {
kDevPerfLvlMap.at((rsmi_dev_perf_level)val));
break;
case kDevGPUMClk: // integer (index within num-freq range)
case kDevGPUSClk: // integer (index within num-freq range)
case kDevPCIEClk: // integer (index within num-freq range)
case kDevDevID: // string (read-only)
default:
break;
}
@@ -255,9 +257,6 @@ int Device::writeDevInfo(DevInfoTypes type, std::string val) {
case kDevPowerODVoltage:
return writeDevInfoStr(type, val);
case kDevOverDriveLevel:
case kDevPerfLevel:
case kDevDevID:
default:
break;
}
@@ -315,6 +314,9 @@ int Device::readDevInfo(DevInfoTypes type, uint64_t *val) {
int ret;
switch (type) {
case kDevDevID:
case kDevSubSysDevID:
case kDevSubSysVendorID:
case kDevVendorID:
ret = readDevInfoStr(type, &tempStr);
RET_IF_NONZERO(ret);
*val = std::stoi(tempStr, 0, 16);
@@ -369,6 +371,9 @@ int Device::readDevInfo(DevInfoTypes type, std::string *val) {
case kDevUsage:
case kDevOverDriveLevel:
case kDevDevID:
case kDevSubSysDevID:
case kDevSubSysVendorID:
case kDevVendorID:
case kDevVBiosVer:
case kDevPCIEThruPut:
return readDevInfoStr(type, val);
+6 -5
View File
@@ -136,7 +136,8 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) {
tmp = in_name.copy(name, 12);
assert(tmp == 12);
// BDFID = ((<BUS> & 0x1f) << 8) | ((device& 0x1f) <<3 ) | (function & 0x7).
// BDFID = ((<DOMAIN> & 0xffff) << 13) | ((<BUS> & 0x1f) << 8) |
// ((device& 0x1f) <<3 ) | (function & 0x7)
*bdfid = 0;
name_start = name;
p = name_start;
@@ -146,10 +147,10 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) {
if (*p != ':' || p - name_start != 4) {
return false;
}
// We are ignoring the domain part for now as KFD is not encoding it yet
*bdfid |= tmp << 13;
// Match this: xxxx:XX:xx.x
p++;
p++; // Skip past ':'
tmp = std::strtoul(p, &p, 16);
if (*p != ':' || p - name_start != 7) {
return false;
@@ -157,7 +158,7 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) {
*bdfid |= tmp << 8;
// Match this: xxxx:xx:XX.x
p++;
p++; // Skip past ':'
tmp = std::strtoul(p, &p, 16);
if (*p != '.' || p - name_start != 10) {
return false;
@@ -165,7 +166,7 @@ static bool is_bdfid_path_str(const std::string in_name, uint64_t *bdfid) {
*bdfid |= tmp << 3;
// Match this: xxxx:xx:xx.X
p++;
p++; // Skip past '.'
tmp = std::strtoul(p, &p, 16);
if (*p != '\0' || p - name_start != 12) {
return false;