Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMD Slow Memory Bandwidth Allocation 0.1 #235

Closed
wants to merge 32 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
3296b7c
lib: Introduce Slow Memory Bandwidth Allocation
babumoger Feb 16, 2023
fe1620e
lib: Discover SMBA feature using cpuid method
babumoger Feb 16, 2023
e67aaea
lib: Discover SMBA feature using resctrl sysfs interface
babumoger Feb 16, 2023
39ac9e1
lib: Add Slow Memory Bandwidth Allocation MSR definition
babumoger Feb 16, 2023
662026d
lib: Introduce pqos_cpu_get_one_by_smba_id
babumoger Feb 16, 2023
f0c7a91
lib: Introduce pqos_smba_get_cos_num
babumoger Feb 16, 2023
6f36194
lib: Introduce smba_get and smba_set wrapper APIs
babumoger Feb 16, 2023
3f051d1
lib: Implement the function hw_smba_get_amd
babumoger Feb 16, 2023
cdc4006
lib: Implement the function hw_smba_set_amd
babumoger Feb 16, 2023
22a86e4
lib: Introduce data structures to support SMBA feature
babumoger Feb 16, 2023
4573003
lib: Introduce pqos_cpu_get_smba_ids
babumoger Feb 16, 2023
a4a6151
lib: Introduce resctrl_schemata_smba_get
babumoger Feb 16, 2023
a158d88
lib: Update the function resctrl_schemata_alloc to support SMBA feature
babumoger Feb 16, 2023
f1f0ade
lib: Update resctrl_schemata functions to support SMBA
babumoger Feb 16, 2023
abed62f
lib: Introduce os_smba_get_amd to read the COS information
babumoger Feb 16, 2023
f5736ed
lib: Add resctrl_schemata functions to support SMBA
babumoger Feb 16, 2023
dc27097
lib: Introduce os_smba_set_amd to update schemata for SMBA
babumoger Feb 16, 2023
401d8b8
pqos: Introduce set_smba_cos for SMBA
babumoger Feb 16, 2023
7bee5f5
pqos: Update alloc_apply to support SMBA feature
babumoger Feb 16, 2023
d362b50
pqos: Introduce cap_print_features_smba
babumoger Feb 16, 2023
61d9538
pqos: Update print_per_socket_config for SMBA
babumoger Feb 16, 2023
7a564a5
pqos: Introduce _pqos_cap_smba_change
babumoger Feb 16, 2023
2ff3f69
lib: Update the function pqos_alloc_reset to reset SMBA COS settings
babumoger Feb 16, 2023
03d5bd6
rdtset: Update the rdt data structure to support SMBA feature
babumoger Feb 16, 2023
08b05fb
rdtset: Add the support for SMBA feature
babumoger Feb 16, 2023
3ec2a99
rdtset: Update alloc_init and alloc_fini for SMBA feature
babumoger Feb 16, 2023
06ef3cf
rdtset: Update cfg_configure_cos to support SMBA feature
babumoger Feb 16, 2023
2b409c2
rdtset: Update cfg_set_pids to support SMBA feature
babumoger Feb 16, 2023
4055afd
rdtset: Update cfg_set_cores_os for SMBA feature
babumoger Feb 16, 2023
edf6448
lib: Update cfg_set_cores_msr to support SMBA feature
babumoger Feb 16, 2023
99afb97
pqos: Update pqos manpage for SMBA feature
babumoger Feb 16, 2023
d58e53b
rdtset: Update rdtset manpage to support SMBA feature
babumoger Feb 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
218 changes: 210 additions & 8 deletions lib/allocation.c

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions lib/allocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum pqos_technology {
PQOS_TECHNOLOGY_L3CA = 1 << PQOS_CAP_TYPE_L3CA,
PQOS_TECHNOLOGY_L2CA = 1 << PQOS_CAP_TYPE_L2CA,
PQOS_TECHNOLOGY_MBA = 1 << PQOS_CAP_TYPE_MBA,
PQOS_TECHNOLOGY_SMBA = 1 << PQOS_CAP_TYPE_SMBA,
PQOS_TECHNOLOGY_ALL = -1
};

Expand Down Expand Up @@ -107,6 +108,7 @@ PQOS_LOCAL int hw_alloc_assoc_read(const unsigned lcore, unsigned *class_id);
* @param [in] l3cat_id L3 CAT resource id
* @param [in] l2cat_id L2 CAT resource id
* @param [in] mba_id MBA resource id
* @param [in] smba_id SMBA resource id
* @param [out] class_id unused COS
*
* NOTE: It is our assumption that mba id and cat ids are same for
Expand All @@ -119,6 +121,7 @@ PQOS_LOCAL int hw_alloc_assoc_unused(const unsigned technology,
unsigned l3cat_id,
unsigned l2cat_id,
unsigned mba_id,
unsigned smba_id,
unsigned *class_id);

/**
Expand Down Expand Up @@ -422,6 +425,41 @@ PQOS_LOCAL int hw_mba_get_amd(const unsigned mba_id,
unsigned *num_cos,
struct pqos_mba *mba_tab);

/**
* @brief Hardware interface to read SMBA from \a smba_id
* @NOTE: This function is specific to AMD
*
* @param [in] smba_id SMBA resource id
* @param [in] max_num_cos maximum number of classes of service
* that can be accommodated at \a smba_tab
* @param [out] num_cos number of classes of service read into \a smba_tab
* @param [out] smba_tab table with read classes of service
*
* @return Operations status
* @retval PQOS_RETVAL_OK on success
*/
PQOS_LOCAL int hw_smba_get_amd(const unsigned smba_id,
const unsigned max_num_cos,
unsigned *num_cos,
struct pqos_mba *smba_tab);
/**
* @brief Hardware interface to set classes of service
* defined by \a requested on \a smba_id
* @NOTE: This function is specific to AMD
*
* @param [in] smba_id
* @param [in] num_cos number of classes of service at \a ca
* @param [in] requested table with class of service definitions
* @param [out] actual table with class of service definitions
*
* @return Operations status
* @retval PQOS_RETVAL_OK on success
*/
PQOS_LOCAL int hw_smba_set_amd(const unsigned smba_id,
const unsigned num_cos,
const struct pqos_mba *requested,
struct pqos_mba *actual);

#ifdef __cplusplus
}
#endif
Expand Down
96 changes: 94 additions & 2 deletions lib/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,16 @@ static struct pqos_api {
const unsigned num_cos,
const struct pqos_mba *requested,
struct pqos_mba *actual);
/** Get SMBA */
int (*smba_get)(const unsigned smba_id,
const unsigned max_num_cos,
unsigned *num_cos,
struct pqos_mba *smba_tab);
/** Set SMBA mask */
int (*smba_set)(const unsigned smba_id,
const unsigned num_cos,
const struct pqos_mba *requested,
struct pqos_mba *actual);

/** Retrieves tasks associated with COS */
unsigned *(*pid_get_pid_assoc)(const unsigned class_id,
Expand Down Expand Up @@ -193,6 +203,8 @@ api_init(int interface, enum pqos_vendor vendor)
if (vendor == PQOS_VENDOR_AMD) {
api.mba_get = hw_mba_get_amd;
api.mba_set = hw_mba_set_amd;
api.smba_get = hw_smba_get_amd;
api.smba_set = hw_smba_set_amd;
} else {
api.mon_start_uncore = hw_mon_start_uncore;
api.mba_get = hw_mba_get;
Expand Down Expand Up @@ -226,6 +238,8 @@ api_init(int interface, enum pqos_vendor vendor)
if (vendor == PQOS_VENDOR_AMD) {
api.mba_get = os_mba_get_amd;
api.mba_set = os_mba_set_amd;
api.smba_get = os_smba_get_amd;
api.smba_set = os_smba_set_amd;
} else {
api.mba_get = os_mba_get;
api.mba_set = os_mba_set;
Expand Down Expand Up @@ -305,9 +319,10 @@ pqos_alloc_assign(const unsigned technology,
const int l2_req = ((technology & (1 << PQOS_CAP_TYPE_L2CA)) != 0);
const int l3_req = ((technology & (1 << PQOS_CAP_TYPE_L3CA)) != 0);
const int mba_req = ((technology & (1 << PQOS_CAP_TYPE_MBA)) != 0);
const int smba_req = ((technology & (1 << PQOS_CAP_TYPE_SMBA)) != 0);

if (core_num == 0 || core_array == NULL || class_id == NULL ||
!(l2_req || l3_req || mba_req))
!(l2_req || l3_req || mba_req || smba_req))
return PQOS_RETVAL_PARAM;

return API_CALL(alloc_assign, technology, core_array, core_num,
Expand Down Expand Up @@ -348,7 +363,8 @@ pqos_alloc_release_pid(const pid_t *task_array, const unsigned task_num)
int
pqos_alloc_reset(const enum pqos_cdp_config l3_cdp_cfg,
const enum pqos_cdp_config l2_cdp_cfg,
const enum pqos_mba_config mba_cfg)
const enum pqos_mba_config mba_cfg,
const enum pqos_mba_config smba_cfg)
{
struct pqos_alloc_config cfg;

Expand All @@ -357,6 +373,7 @@ pqos_alloc_reset(const enum pqos_cdp_config l3_cdp_cfg,
cfg.l3_cdp = l3_cdp_cfg;
cfg.l2_cdp = l2_cdp_cfg;
cfg.mba = mba_cfg;
cfg.smba = smba_cfg;

return pqos_alloc_reset_config(&cfg);
}
Expand Down Expand Up @@ -391,6 +408,15 @@ pqos_alloc_reset_config(const struct pqos_alloc_config *cfg)
cfg->mba);
return PQOS_RETVAL_PARAM;
}

if (cfg->smba != PQOS_MBA_ANY &&
cfg->smba != PQOS_MBA_DEFAULT &&
cfg->smba != PQOS_MBA_CTRL) {
LOG_ERROR(
"Unrecognized SMBA configuration setting %d!\n",
cfg->mba);
return PQOS_RETVAL_PARAM;
}
}

return API_CALL(alloc_reset, cfg);
Expand Down Expand Up @@ -639,6 +665,72 @@ pqos_mba_get(const unsigned mba_id,
return API_CALL(mba_get, mba_id, max_num_cos, num_cos, mba_tab);
}

/*
* =======================================
* Slow Memory Bandwidth Allocation
* =======================================
*/
int
pqos_smba_set(const unsigned smba_id,
const unsigned num_cos,
const struct pqos_mba *requested,
struct pqos_mba *actual)
{
int ret;
unsigned i;

if (requested == NULL || num_cos == 0)
return PQOS_RETVAL_PARAM;

lock_get();

ret = _pqos_check_init(1);
if (ret != PQOS_RETVAL_OK) {
lock_release();
return ret;
}

/**
* Check if SMBA rate is within allowed range
*/
for (i = 0; i < num_cos; i++) {
const struct cpuinfo_config *vconfig;

cpuinfo_get_config(&vconfig);
if (requested[i].ctrl == 0 &&
(requested[i].mb_max == 0 ||
requested[i].mb_max > vconfig->mba_max)) {
LOG_ERROR("SMBA COS%u rate out of range (from 1-%d)!\n",
requested[i].class_id, vconfig->mba_max);
lock_release();
return PQOS_RETVAL_PARAM;
}
}

if (api.smba_set != NULL)
ret = api.smba_set(smba_id, num_cos, requested, actual);
else {
LOG_INFO(UNSUPPORTED_INTERFACE);
ret = PQOS_RETVAL_RESOURCE;
}

lock_release();

return ret;
}

int
pqos_smba_get(const unsigned smba_id,
const unsigned max_num_cos,
unsigned *num_cos,
struct pqos_mba *smba_tab)
{
if (num_cos == NULL || smba_tab == NULL || max_num_cos == 0)
return PQOS_RETVAL_PARAM;

return API_CALL(smba_get, smba_id, max_num_cos, num_cos, smba_tab);
}

/*
* =======================================
* Monitoring
Expand Down
128 changes: 128 additions & 0 deletions lib/cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,54 @@ cap_mba_discover(struct pqos_cap_mba **r_cap,
return ret;
}

/**
* @brief Discovers support of SMBA
*
* @param[out] r_cap place to store SMBA capabilities structure
* @param[in] cpu detected cpu topology
* @param[in] iface Selected interface
*
* @return Operation status
* @retval PQOS_RETVAL_OK success
*/
static int
cap_smba_discover(struct pqos_cap_mba **r_cap,
const struct pqos_cpuinfo *cpu,
const enum pqos_interface iface)
{
struct pqos_cap_mba *cap = NULL;
int ret = PQOS_RETVAL_OK;

cap = (struct pqos_cap_mba *)malloc(sizeof(*cap));
if (cap == NULL)
return PQOS_RETVAL_RESOURCE;

switch (iface) {
case PQOS_INTER_MSR:
if (cpu->vendor == PQOS_VENDOR_AMD)
ret = amd_cap_smba_discover(cap, cpu);
else
ret = PQOS_RETVAL_RESOURCE;
break;
#ifdef __linux__
case PQOS_INTER_OS:
case PQOS_INTER_OS_RESCTRL_MON:
ret = os_cap_smba_discover(cap, cpu);
break;
#endif
default:
ret = PQOS_RETVAL_RESOURCE;
break;
}

if (ret == PQOS_RETVAL_OK)
*r_cap = cap;
else
free(cap);

return ret;
}

/**
* @brief Runs detection of platform monitoring and allocation capabilities
*
Expand All @@ -318,6 +366,7 @@ discover_capabilities(struct pqos_cap **p_cap,
struct pqos_cap_l3ca *det_l3ca = NULL;
struct pqos_cap_l2ca *det_l2ca = NULL;
struct pqos_cap_mba *det_mba = NULL;
struct pqos_cap_mba *det_smba = NULL;
struct pqos_cap *_cap = NULL;
unsigned sz = 0;
int ret = PQOS_RETVAL_RESOURCE;
Expand Down Expand Up @@ -423,6 +472,29 @@ discover_capabilities(struct pqos_cap **p_cap,
goto error_exit;
}

/**
* Slow Memory bandwidth allocation init
*/
ret = cap_smba_discover(&det_smba, cpu, inter);
switch (ret) {
case PQOS_RETVAL_OK:
LOG_INFO("SMBA capability detected\n");
LOG_INFO("SMBA details: "
"#COS=%u, %slinear, max=%u, step=%u\n",
det_smba->num_classes,
det_smba->is_linear ? "" : "non-",
det_smba->throttle_max, det_smba->throttle_step);
sz += sizeof(struct pqos_capability);
break;
case PQOS_RETVAL_RESOURCE:
LOG_INFO("SMBA capability not detected\n");
break;
default:
LOG_ERROR("Fatal error encounter in SMBA discovery!\n");
ret = PQOS_RETVAL_ERROR;
goto error_exit;
}

if (sz == 0) {
LOG_ERROR("No Platform QoS capability discovered\n");
ret = PQOS_RETVAL_ERROR;
Expand Down Expand Up @@ -481,6 +553,13 @@ discover_capabilities(struct pqos_cap **p_cap,
#endif
}

if (det_smba != NULL) {
_cap->capabilities[_cap->num_cap].type = PQOS_CAP_TYPE_SMBA;
_cap->capabilities[_cap->num_cap].u.smba = det_smba;
_cap->num_cap++;
ret = PQOS_RETVAL_OK;
}

(*p_cap) = _cap;

error_exit:
Expand Down Expand Up @@ -1029,6 +1108,55 @@ _pqos_cap_mba_change(const enum pqos_mba_config cfg)
}
}

void
_pqos_cap_smba_change(const enum pqos_mba_config cfg)
{
struct pqos_cap_mba *smba_cap = NULL;
unsigned i;
#ifdef __linux__
enum pqos_interface interface = _pqos_get_inter();
#endif

ASSERT(cfg == PQOS_MBA_DEFAULT || cfg == PQOS_MBA_CTRL ||
cfg == PQOS_MBA_ANY);
ASSERT(m_cap != NULL);

if (m_cap == NULL)
return;

for (i = 0; i < m_cap->num_cap && smba_cap == NULL; i++)
if (m_cap->capabilities[i].type == PQOS_CAP_TYPE_SMBA) {
smba_cap = m_cap->capabilities[i].u.smba;
break;
}

if (smba_cap == NULL)
return;

#ifdef __linux__
/* refresh number of classes */
if (interface == PQOS_INTER_OS ||
interface == PQOS_INTER_OS_RESCTRL_MON) {
int ret;
unsigned num_classes;

ret = resctrl_alloc_get_num_closids(&num_classes);
if (ret == PQOS_RETVAL_OK)
smba_cap->num_classes = num_classes;
}
#endif

if (cfg == PQOS_MBA_DEFAULT)
smba_cap->ctrl_on = 0;
else if (cfg == PQOS_MBA_CTRL) {
#ifdef __linux__
if (interface != PQOS_INTER_MSR)
smba_cap->ctrl = 1;
#endif
smba_cap->ctrl_on = 1;
}
}

const struct pqos_cap *
_pqos_get_cap(void)
{
Expand Down
10 changes: 10 additions & 0 deletions lib/cap.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ PQOS_LOCAL void _pqos_cap_l2cdp_change(const enum pqos_cdp_config cdp);
*/
PQOS_LOCAL void _pqos_cap_mba_change(const enum pqos_mba_config cfg);

/**
* @brief Modifies SMBA capability structure upon MBA CTRL config change
*
* Limited error checks done in this function and no errors reported.
* It is up to caller to check for MBA & CTRL support.
*
* @param [in] cfg MBA CTRL configuration
*/
PQOS_LOCAL void _pqos_cap_smba_change(const enum pqos_mba_config cfg);

/**
* @brief Checks library initialization state
*
Expand Down
Loading