fix: [SWDEV-442525] [rocm/amd_smi_lib]

Fixes gpu_process_list

Code changes related to the following:
  * amdsmi_get_gpu_process_list()
  * CLI
  * Examples
  * Unit tests
  * Changelog
  * Readme
  * rocm_smi_lib commit: 677433b367

Change-Id: I9210fbca7a5da92d0a8b472b72ca82597c8e4fb5
Signed-off-by: Oliveira, Daniel <daniel.oliveira@amd.com>
This commit is contained in:
Oliveira, Daniel
2024-03-14 05:53:26 -05:00
orang tua 9800156a7a
melakukan 08e2e21bab
14 mengubah file dengan 380 tambahan dan 246 penghapusan
+39 -60
Melihat File
@@ -1785,76 +1785,55 @@ amdsmi_get_gpu_total_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_
}
amdsmi_status_t
amdsmi_get_gpu_process_list(amdsmi_processor_handle processor_handle, uint32_t *max_processes, amdsmi_process_handle_t *list) {
amdsmi_get_gpu_process_list(amdsmi_processor_handle processor_handle, uint32_t *max_processes, amdsmi_proc_info_t *list) {
AMDSMI_CHECK_INIT();
if (max_processes == nullptr) {
if (!max_processes) {
return AMDSMI_STATUS_INVAL;
}
std::vector<long int> pids;
uint32_t i = 0;
uint64_t size = 0;
amdsmi_status_t status;
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
amdsmi_status_t status_code = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (status_code != amdsmi_status_t::AMDSMI_STATUS_SUCCESS) {
return status_code;
}
if (gpu_device->check_if_drm_is_supported()){
amdsmi_bdf_t bdf = gpu_device->get_bdf();
status = gpuvsmi_get_pids(bdf, pids, &size);
if (status != AMDSMI_STATUS_SUCCESS) {
return status;
}
if (*max_processes == 0 || (pids.size() == 0)) {
*max_processes = (uint32_t)pids.size();
return AMDSMI_STATUS_SUCCESS;
}
if (!list) {
return AMDSMI_STATUS_INVAL;
}
if (*max_processes < pids.size()) {
return AMDSMI_STATUS_OUT_OF_RESOURCES;
}
for (auto &pid : pids) {
if (i >= *max_processes) {
break;
auto compute_process_list = gpu_device->amdgpu_get_compute_process_list();
if ((*max_processes == 0) || compute_process_list.empty()) {
*max_processes = static_cast<uint32_t>(compute_process_list.size());
return amdsmi_status_t::AMDSMI_STATUS_SUCCESS;
}
if (!list) {
return amdsmi_status_t::AMDSMI_STATUS_INVAL;
}
const auto max_processes_original_size(*max_processes);
auto idx = uint32_t(0);
auto is_required_previlegies_required(false);
for (auto& process : compute_process_list) {
if (idx < *max_processes) {
list[idx++] = static_cast<amdsmi_proc_info_t>(process.second);
// Note: If we could not read the process info for an existing process,
// that is likely a permission error.
if (!is_required_previlegies_required && std::string(process.second.name).empty()) {
is_required_previlegies_required = true;
}
list[i++] = (uint32_t)pid;
} else {
break;
}
*max_processes = (uint32_t)pids.size();
}
else {
// rocm
}
return AMDSMI_STATUS_SUCCESS;
}
amdsmi_status_t
amdsmi_get_gpu_process_info(amdsmi_processor_handle processor_handle, amdsmi_process_handle_t process, amdsmi_proc_info_t *info) {
AMDSMI_CHECK_INIT();
if (info == nullptr) {
return AMDSMI_STATUS_INVAL;
}
amd::smi::AMDSmiGPUDevice* gpu_device = nullptr;
amdsmi_status_t r = get_gpu_device_from_handle(processor_handle, &gpu_device);
if (r != AMDSMI_STATUS_SUCCESS)
return r;
amdsmi_status_t status;
if (gpu_device->check_if_drm_is_supported()) {
status = gpuvsmi_get_pid_info(gpu_device->get_bdf(), process, *info);
if (status != AMDSMI_STATUS_SUCCESS) return status;
}
else {
// rocm
}
return AMDSMI_STATUS_SUCCESS;
// Note: If the reserved size for processes is smaller than the number of
// actual processes running. The AMDSMI_STATUS_OUT_OF_RESOURCES is
// an indication the caller should handle the situation (resize).
// The max_processes is always changed to reflect the actual size of
// list of processes running, so the caller knows where it is at.
// Holding a copy of max_process before it is passed in will be helpful
// for the caller.
status_code = is_required_previlegies_required
? amdsmi_status_t::AMDSMI_STATUS_NO_PERM : AMDSMI_STATUS_SUCCESS;
*max_processes = static_cast<uint32_t>(compute_process_list.size());
return (max_processes_original_size >= static_cast<uint32_t>(compute_process_list.size()))
? status_code : amdsmi_status_t::AMDSMI_STATUS_OUT_OF_RESOURCES;
}
amdsmi_status_t
+154 -1
Melihat File
@@ -41,10 +41,16 @@
*
*/
#include <functional>
#include "amd_smi/impl/amd_smi_gpu_device.h"
#include "amd_smi/impl/amd_smi_common.h"
#include "amd_smi/impl/fdinfo.h"
#include "rocm_smi/rocm_smi_kfd.h"
#include "rocm_smi/rocm_smi_utils.h"
#include <functional>
#include <map>
#include <memory>
#include <unordered_set>
namespace amd {
namespace smi {
@@ -148,6 +154,153 @@ amdsmi_status_t AMDSmiGPUDevice::amdgpu_query_vbios(void *info) const {
return drm_.amdgpu_query_vbios(fd, info);
}
int32_t AMDSmiGPUDevice::get_compute_process_list_impl(GPUComputeProcessList_t& compute_process_list,
ComputeProcessListType_t list_type)
{
/**
* The first call to GetProcessInfo() helps to find the size it needs,
* so we can create a tailored size list.
*/
auto status_code(rsmi_status_t::RSMI_STATUS_SUCCESS);
auto list_process_running_size = uint32_t(0);
auto list_process_allocation_size = uint32_t(0);
status_code = rsmi_compute_process_info_get(nullptr, &list_process_running_size);
if ((status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) || (list_process_running_size <= 0)) {
return status_code;
}
/**
* The second call to GetProcessInfo() helps to set proper sizes for both,
* the raw array of processes (amdsmi_process_info_t) and list of processes (amdsmi_proc_info_t).
*/
using RsmiDeviceList_t = uint32_t[];
using RsmiProcessList_t = rsmi_process_info_t[];
std::unique_ptr<RsmiProcessList_t> list_all_processes_ptr = std::make_unique<RsmiProcessList_t>(list_process_running_size);
list_process_allocation_size = list_process_running_size;
status_code = rsmi_compute_process_info_get(list_all_processes_ptr.get(), &list_process_allocation_size);
if (status_code) {
return status_code;
}
// Restore the original size to read
list_process_running_size = list_process_allocation_size;
if (list_process_running_size <= 0) {
return rsmi_status_t::RSMI_STATUS_NOT_FOUND;
}
/**
* Setup for the cases where the process list is by device.
*/
auto list_device_running_size = uint32_t(0);
auto list_device_allocation_size = uint32_t(0);
status_code = rsmi_num_monitor_devices(&list_device_running_size);
if ((status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) || (list_device_running_size <= 0)) {
return status_code;
}
/**
* Complete the process information
*/
auto get_process_info = [&](const rsmi_process_info_t& rsmi_proc_info, amdsmi_proc_info_t& asmi_proc_info) {
auto status_code = gpuvsmi_get_pid_info(get_bdf(), rsmi_proc_info.process_id, asmi_proc_info);
// If we cannot get the info from sysfs, save the minimum info
if (status_code != amdsmi_status_t::AMDSMI_STATUS_SUCCESS) {
asmi_proc_info.pid = rsmi_proc_info.process_id;
asmi_proc_info.memory_usage.vram_mem = rsmi_proc_info.vram_usage;
}
return status_code;
};
/**
* Get process information
*/
auto update_list_by_running_process = [&](const uint32_t process_id) {
auto status_result(true);
rsmi_process_info_t rsmi_proc_info{};
auto status_code = rsmi_compute_process_info_by_pid_get(process_id, &rsmi_proc_info);
if (status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) {
status_result = false;
return status_result;
}
amdsmi_proc_info_t tmp_asmi_proc_info{};
get_process_info(rsmi_proc_info, tmp_asmi_proc_info);
compute_process_list.emplace(process_id, tmp_asmi_proc_info);
return status_result;
};
/**
* Devices used by a process.
*/
auto update_list_by_running_device = [&](const uint32_t process_id,
const uint32_t proc_addr_id) {
// Get all devices running this process
auto status_result(true);
std::unique_ptr<RsmiDeviceList_t> list_device_ptr = std::make_unique<RsmiDeviceList_t>(list_device_running_size);
list_device_allocation_size = list_device_running_size;
auto status_code = rsmi_compute_process_gpus_get(process_id, list_device_ptr.get(), &list_device_allocation_size);
if (status_code != rsmi_status_t::RSMI_STATUS_SUCCESS) {
status_result = false;
return status_result;
}
for (auto device_idx = uint32_t(0); device_idx < list_device_allocation_size; ++device_idx) {
// Is this device running this process?
if (list_device_ptr[device_idx] == get_gpu_id()) {
rsmi_process_info_t rsmi_dev_proc_info{};
auto status_code = rsmi_compute_process_info_by_device_get(process_id, list_device_ptr[device_idx], &rsmi_dev_proc_info);
if ((status_code == rsmi_status_t::RSMI_STATUS_SUCCESS) &&
((rsmi_dev_proc_info.process_id == process_id) && (rsmi_dev_proc_info.pasid == proc_addr_id))) {
amdsmi_proc_info_t tmp_asmi_proc_info{};
get_process_info(rsmi_dev_proc_info, tmp_asmi_proc_info);
compute_process_list.emplace(process_id, tmp_asmi_proc_info);
}
}
}
return status_result;
};
/**
* Transfer/Save the ones linked to this device.
*/
compute_process_list.clear();
for (auto process_idx = uint32_t(0); process_idx < list_process_running_size; ++process_idx) {
if (list_type == ComputeProcessListType_t::kAllProcesses) {
if (update_list_by_running_process(list_all_processes_ptr[process_idx].process_id)) {
}
}
if (list_type == ComputeProcessListType_t::kAllProcessesOnDevice) {
if (update_list_by_running_device(list_all_processes_ptr[process_idx].process_id,
list_all_processes_ptr[process_idx].pasid)) {
}
}
}
return status_code;
}
const GPUComputeProcessList_t& AMDSmiGPUDevice::amdgpu_get_compute_process_list(ComputeProcessListType_t list_type)
{
auto error_code = get_compute_process_list_impl(compute_process_list_, list_type);
if (error_code) {
compute_process_list_.clear();
}
return compute_process_list_;
}
} // namespace smi
} // namespace amd
+6 -5
Melihat File
@@ -220,12 +220,10 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid,
}
}
closedir(d);
if (!pasids.size())
return AMDSMI_STATUS_NOT_FOUND;
// Note: If possible at all, try to get the name of the process/container.
// In case the other info fail, get at least something.
std::ifstream filename(name_path.c_str());
std::string name;
@@ -252,9 +250,12 @@ amdsmi_status_t gpuvsmi_get_pid_info(const amdsmi_bdf_t &bdf, long int pid,
if (strlen(info.container_name) > 0)
break;
}
info.pid = (uint32_t)pid;
if (!pasids.size()) {
return AMDSMI_STATUS_NOT_FOUND;
}
return AMDSMI_STATUS_SUCCESS;
}