[SWDEV-531379] Fix config (#183)

* [SWDEV-531379] Fix config

Signed-off-by: adapryor <Adam.pryor@amd.com>
Change-Id: Ie1bd6903235016a185dd93fbac0a87658fb12a62

* Fix group field find

Signed-off-by: adapryor <Adam.pryor@amd.com>
Change-Id: I1f8c62615327df4b5ca916b158b4882a3d5a59d0

* fixes

Signed-off-by: adapryor <Adam.pryor@amd.com>
Change-Id: I971f3e12e293ea9e5d4d67db64d8d7217b87561c

---------

Signed-off-by: adapryor <Adam.pryor@amd.com>
This commit is contained in:
Pryor, Adam
2025-06-09 13:55:15 -05:00
committed by GitHub
parent 85b619b2f0
commit 8663702737
2 changed files with 131 additions and 50 deletions
+2 -1
View File
@@ -44,13 +44,14 @@ class RdciConfigSubSystem : public RdciSubSystem {
private:
void show_help() const;
void display_config_settings(rdc_config_setting_list_t& rdc_configs_list);
rdc_status_t rdc_group_field_find(rdc_handle_t p_rdc_handle, const char* field_group_name,
rdc_field_grp_t* out_field_group_id);
config_command_type_t config_cmd_;
static constexpr rdc_field_grp_t JOB_FIELD_ID = 1;
uint32_t group_id_;
uint32_t power_limit_;
uint64_t gfx_max_clock_;
uint64_t memory_max_clock_;
rdc_field_grp_t fgid_;
};
} // namespace rdc
+129 -49
View File
@@ -22,6 +22,7 @@ THE SOFTWARE.
#include "RdciConfigSubSystem.h"
#include <getopt.h>
#include <string.h>
#include <unistd.h>
#include <algorithm>
@@ -37,23 +38,17 @@ THE SOFTWARE.
static constexpr uint32_t TABLE_COLUMN_WIDTH = 20;
static std::string make_fg_name(rdc_gpu_group_t gid) {
return std::string("RdciConfigSubSystem_group") + std::to_string(gid);
}
namespace amd {
namespace rdc {
RdciConfigSubSystem::RdciConfigSubSystem()
: config_cmd_(CONFIG_COMMAND_NONE),
power_limit_(0),
gfx_max_clock_(0),
memory_max_clock_(0),
fgid_(0) {}
: config_cmd_(CONFIG_COMMAND_NONE), power_limit_(0), gfx_max_clock_(0), memory_max_clock_(0) {}
RdciConfigSubSystem::~RdciConfigSubSystem() {
if (fgid_ != JOB_FIELD_ID) {
rdc_field_unwatch(rdc_handle_, group_id_, fgid_);
rdc_group_field_destroy(rdc_handle_, fgid_);
fgid_ = JOB_FIELD_ID;
}
}
RdciConfigSubSystem::~RdciConfigSubSystem() {}
void RdciConfigSubSystem::parse_cmd_opts(int argc, char** argv) {
const int JSON_OPTIONS = 1001;
@@ -148,7 +143,15 @@ void RdciConfigSubSystem::process() {
switch (config_cmd_) {
case CONFIG_COMMAND_SET: {
if (gfx_max_clock_ == 0 && power_limit_ == 0 && memory_max_clock_ == 0) {
show_help();
throw RdcException(
RDC_ST_BAD_PARAMETER,
"Must specify at least one of --powerlimit, --gfxmaxclk or --memclk when using --set");
}
rdc_config_setting_t setting;
if (gfx_max_clock_ != 0) {
setting.type = RDC_CFG_GFX_CLOCK_LIMIT;
setting.target_value = gfx_max_clock_;
@@ -166,64 +169,107 @@ void RdciConfigSubSystem::process() {
setting.target_value = memory_max_clock_;
result = rdc_config_set(rdc_handle_, group_id_, setting);
}
if (result == RDC_ST_OK) {
if (is_json_output()) {
json_ss << "{"
<< "\"group_id\": \"" << group_id_ << "\", \"status\": \"ok\""
<< "}";
} else {
std::cout << "Successfully configured GPU Id belongs to group: " << group_id_
<< std::endl;
}
std::cout << json_ss.str() << std::endl;
return;
if (result != RDC_ST_OK) {
break;
}
break;
}
case CONFIG_COMMAND_GET: {
// Add the default job stats fields
std::vector<rdc_field_t> job_fields = {RDC_FI_GPU_CLOCK, RDC_FI_MEM_CLOCK,
RDC_FI_POWER_USAGE};
static const char job_field_group[] = "RdciConfigSubSystem";
// If watch group exists, get existing watched fields, tear group down and make new one
std::vector<rdc_field_t> job_fields;
rdc_field_grp_t old_fgid;
std::string fg_name = make_fg_name(group_id_);
if (rdc_group_field_find(rdc_handle_, fg_name.c_str(), &old_fgid) == RDC_ST_OK) {
rdc_field_group_info_t info{};
result = rdc_group_field_get_info(rdc_handle_, old_fgid, &info);
if (result != RDC_ST_OK) {
std::cout << "Error unable to get group info for field group: " << old_fgid << std::endl;
break;
}
for (uint32_t i = 0; i < info.count; ++i) {
job_fields.push_back(info.field_ids[i]);
}
result = rdc_field_unwatch(rdc_handle_, group_id_, old_fgid);
if (result != RDC_ST_OK) {
std::cout << "Error unable to unwatch field group: " << old_fgid << std::endl;
break;
}
rdc_group_field_destroy(rdc_handle_, old_fgid);
if (result != RDC_ST_OK) {
std::cout << "Error unable to destroy field group: " << old_fgid << std::endl;
break;
}
std::cout << "Successfully removed field group: " << old_fgid << std::endl;
}
// Add new and existing fields to watch, ignoring duplicates
auto add_if_new = [&](rdc_field_t f) {
if (std::find(job_fields.begin(), job_fields.end(), f) == job_fields.end())
job_fields.push_back(f);
};
if (gfx_max_clock_) add_if_new(RDC_FI_GPU_CLOCK);
if (power_limit_) add_if_new(RDC_FI_POWER_USAGE);
if (memory_max_clock_) add_if_new(RDC_FI_MEM_CLOCK);
rdc_field_grp_t fgid;
result = rdc_group_field_create(rdc_handle_, job_fields.size(), job_fields.data(),
job_field_group, &fgid_);
fg_name.c_str(), &fgid);
if (result != RDC_ST_OK) {
std::cout << "Error creating field group: " << fgid << std::endl;
break;
}
std::cout << "Successfully created the field group " << fgid << std::endl;
// Start watch
// Start watching all config values
const double max_keep_age = 30060; // Length of time to keep data in field in seconds
const int max_keep_samples = 10;
const int update_frequency = 1000000; // Once per minute
result = rdc_field_watch(rdc_handle_, group_id_, fgid_, update_frequency, max_keep_age,
result = rdc_field_watch(rdc_handle_, group_id_, fgid, update_frequency, max_keep_age,
max_keep_samples);
if (result != RDC_ST_OK) {
std::cout << "Error creating field watch for group id: " + group_id_ << std::endl;
break;
}
if (is_json_output()) {
json_ss << "{"
<< "\"group_id\": \"" << group_id_ << "\", \"status\": \"ok\""
<< "}";
} else {
std::cout << "Successfully configured GPU Id belongs to group: " << group_id_ << std::endl;
}
std::cout << json_ss.str() << std::endl;
return;
}
case CONFIG_COMMAND_GET: {
rdc_config_setting_list_t settings = {0, {}};
result = rdc_config_get(rdc_handle_, group_id_, &settings);
if (result == RDC_ST_OK) {
display_config_settings(settings);
} else if (result == RDC_ST_NOT_FOUND) {
std::cout << "Get config information failed, cache empty " << std::endl;
std::cout << "No configuration found for group " << group_id_ << std::endl;
} else {
std::cout << "Get config information failed " << std::endl;
std::cout << "Error retrieving config for group " << group_id_ << std::endl;
}
// Stop watching the field group
result = rdc_field_unwatch(rdc_handle_, group_id_, fgid_);
if (result != RDC_ST_OK) {
std::cout << "Error stop watch fields. Return: " << rdc_status_string(result);
}
std::cout << "Stop watch group:" << group_id_ << ", field_group:" << fgid_ << std::endl;
// Delete the field group and GPU group
result = rdc_group_field_destroy(rdc_handle_, fgid_);
if (result != RDC_ST_OK) {
std::cout << "Error delete field group. Return: " << rdc_status_string(result);
}
std::cout << "Deleted the field group " << fgid_ << std::endl;
break;
}
case CONFIG_COMMAND_CLEAR: {
result = rdc_config_clear(rdc_handle_, group_id_);
// Delete the field group and GPU group
std::vector<rdc_field_t> job_fields;
rdc_field_grp_t old_fgid;
std::string fg_name = make_fg_name(group_id_);
if (rdc_group_field_find(rdc_handle_, fg_name.c_str(), &old_fgid) == RDC_ST_OK) {
rdc_field_unwatch(rdc_handle_, group_id_, old_fgid);
rdc_group_field_destroy(rdc_handle_, old_fgid);
}
if (result != RDC_ST_OK) {
std::cout << "Error delete field group. Return: " << rdc_status_string(result);
break;
}
std::cout << "Successfully deleted the field group " << old_fgid << std::endl;
if (result == RDC_ST_OK) {
if (is_json_output()) {
json_ss << "\"group_id\": \"" << group_id_ << "\", \"status\": \"ok\"";
@@ -249,6 +295,40 @@ void RdciConfigSubSystem::process() {
}
}
rdc_status_t RdciConfigSubSystem::rdc_group_field_find(rdc_handle_t p_rdc_handle,
const char* field_group_name,
rdc_field_grp_t* out_field_group_id) {
if (p_rdc_handle == nullptr || field_group_name == nullptr || out_field_group_id == nullptr) {
return RDC_ST_BAD_PARAMETER;
}
rdc_field_grp_t field_group_id_list[RDC_MAX_NUM_FIELD_GROUPS];
uint32_t count = 0;
rdc_status_t status = rdc_group_field_get_all_ids(p_rdc_handle, field_group_id_list, &count);
if (status != RDC_ST_OK) {
return status;
}
for (uint32_t i = 0; i < count; ++i) {
rdc_field_group_info_t info;
status = rdc_group_field_get_info(p_rdc_handle, field_group_id_list[i], &info);
if (status != RDC_ST_OK) {
continue;
}
if (strncmp(info.group_name, field_group_name, RDC_MAX_STR_LENGTH) == 0) {
*out_field_group_id = field_group_id_list[i];
return RDC_ST_OK;
}
}
return RDC_ST_NOT_FOUND;
}
// Our display config settings is called with rdc config get.
// We pass in rdc_configs_list which is all our config settings for the specified group.
// We read from the rdc cache, and display the live value of that setting.
// Remember, rdc cache is updated with our watcher values upon config set
void RdciConfigSubSystem::display_config_settings(rdc_config_setting_list_t& rdc_configs_list) {
rdc_status_t result = RDC_ST_OK;
std::stringstream ss, json_ss;