Fallback to kfd node when VRAM sysfs not available

The driver may not expose VRAM sysfs in certain system. Add a
fallback to it.

Change-Id: Ib3be71b4f4d2c79318d5026b0a97f3657d8a97b6


[ROCm/amdsmi commit: a10f00bf57]
Этот коммит содержится в:
Bill(Shuzhou) Liu
2023-08-17 14:36:03 -05:00
родитель 8915ef543c
Коммит 05b5ef35b3
4 изменённых файлов: 125 добавлений и 0 удалений
+10
Просмотреть файл
@@ -36,6 +36,12 @@ struct kfd_ioctl_get_version_args {
__u32 minor_version; /* from KFD */
};
struct kfd_ioctl_get_available_memory_args {
__u64 available; /* from KFD */
__u32 gpu_id; /* to KFD */
__u32 pad;
};
/* For kfd_ioctl_create_queue_args.queue_type. */
#define KFD_IOC_QUEUE_TYPE_COMPUTE 0x0
#define KFD_IOC_QUEUE_TYPE_SDMA 0x1
@@ -726,6 +732,10 @@ struct kfd_ioctl_cross_memory_copy_args {
#define AMDKFD_IOC_CROSS_MEMORY_COPY \
AMDKFD_IOWR(0x22, struct kfd_ioctl_cross_memory_copy_args)
#define AMDKFD_IOC_AVAILABLE_MEMORY \
AMDKFD_IOWR(0x23, struct kfd_ioctl_get_available_memory_args)
#define AMDKFD_COMMAND_START 0x01
#undef AMDKFD_COMMAND_END
#define AMDKFD_COMMAND_END 0x22
+4
Просмотреть файл
@@ -80,6 +80,10 @@ class KFDNode {
uint32_t amdgpu_dev_index(void) const {return amdgpu_dev_index_;}
void set_amdgpu_dev_index(uint32_t val) {amdgpu_dev_index_ = val;}
// Get memory from kfd
int get_total_memory(uint64_t* total);
int get_used_memory(uint64_t* used);
private:
uint32_t node_indx_;
uint32_t amdgpu_dev_index_;
+19
Просмотреть файл
@@ -3077,6 +3077,14 @@ rsmi_dev_memory_total_get(uint32_t dv_ind, rsmi_memory_type_t mem_type,
DEVICE_MUTEX
ret = get_dev_value_int(mem_type_file, dv_ind, total);
// Fallback to KFD reported memory if VRAM total is 0
if (mem_type == RSMI_MEM_TYPE_VRAM && *total == 0) {
GET_DEV_AND_KFDNODE_FROM_INDX
if (kfd_node->get_total_memory(total) == 0 && *total > 0) {
return RSMI_STATUS_SUCCESS;
}
}
return ret;
CATCH
}
@@ -3113,6 +3121,17 @@ rsmi_dev_memory_usage_get(uint32_t dv_ind, rsmi_memory_type_t mem_type,
DEVICE_MUTEX
ret = get_dev_value_int(mem_type_file, dv_ind, used);
// Fallback to KFD reported memory if no VRAM
if (mem_type == RSMI_MEM_TYPE_VRAM && *used == 0) {
GET_DEV_AND_KFDNODE_FROM_INDX
uint64_t total = 0;
ret = get_dev_value_int(amd::smi::kDevMemTotVRAM, dv_ind, &total);
if (total != 0) return ret; // do not need to fallback
if ( kfd_node->get_used_memory(used) == 0 ) {
return RSMI_STATUS_SUCCESS;
}
}
return ret;
CATCH
}
+92
Просмотреть файл
@@ -43,6 +43,9 @@
#include <assert.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <algorithm>
@@ -770,6 +773,95 @@ KFDNode::get_io_link_bandwidth(uint32_t node_to, uint64_t *max_bandwidth,
return 0;
}
// /sys/class/kfd/kfd/topology/nodes/*/mem_banks/*/properties
// size_in_bytes 68702699520
int KFDNode::get_total_memory(uint64_t* total) {
if (total == nullptr) return EINVAL;
*total = 0;
std::string f_path = kKFDNodesPathRoot;
f_path += "/";
f_path += std::to_string(node_indx_);
f_path += "/mem_banks";
auto kfd_node_dir = opendir(f_path.c_str());
if (kfd_node_dir == nullptr) {
return errno;
}
auto dentry = readdir(kfd_node_dir);
while (dentry != nullptr) {
if (dentry->d_name[0] == '.') {
dentry = readdir(kfd_node_dir);
continue;
}
if (!is_number(dentry->d_name)) {
dentry = readdir(kfd_node_dir);
continue;
}
// read "size_in_bytes 68702699520" line
const std::string size_in_bytes_property = "size_in_bytes ";
std::string memory_bank_file = f_path + "/"
+ dentry->d_name + "/properties";
std::ifstream fs(memory_bank_file);
if (!fs) {
dentry = readdir(kfd_node_dir);
continue;
}
std::string line;
while (std::getline(fs, line)) {
if (line.substr(0, size_in_bytes_property.length())
== size_in_bytes_property) {
auto bytes = line.substr(size_in_bytes_property.length());
try {
*total += std::stol(bytes);
break;
} catch(...) {
dentry = readdir(kfd_node_dir);
continue;
}
}
} // end loop for lines in property file
} // end loop for mem_bank directory
if (closedir(kfd_node_dir)) {
std::string err_str = "Failed to close KFD node directory ";
err_str += f_path;
err_str += ".";
perror(err_str.c_str());
return 1;
}
return 0;
}
// ioctl on kfd node device
int KFDNode::get_used_memory(uint64_t* used) {
if (used == nullptr) return EINVAL;
static const char *kPathKFDIoctl = "/dev/kfd";
int kfd_fd = open(kPathKFDIoctl, O_RDWR | O_CLOEXEC);
if (kfd_fd <= 0) {
return 1;
}
struct kfd_ioctl_get_available_memory_args mem = {0, 0, 0};
mem.gpu_id = gpu_id_;
if (ioctl(kfd_fd, AMDKFD_IOC_AVAILABLE_MEMORY , &mem) != 0) {
close(kfd_fd);
return 1;
}
close(kfd_fd);
// used = total - available
uint64_t total = 0;
int ret = get_total_memory(&total);
if (ret == 0 && total > 0 && mem.available < total) {
*used = total - mem.available;
return 0;
}
return 1;
}
} // namespace smi
} // namespace amd