/* * BSD LICENSE * * Copyright(c) 2014-2020 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** * @brief Platform QoS API and data structure definition * * API from this file is implemented by the following: * cap.c, allocation.c, monitoring.c and utils.c */ #ifndef __PQOS_H__ #define __PQOS_H__ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* * ======================================= * Various defines * ======================================= */ #define PQOS_VERSION 40000 /**< version 4.0.0 */ #define PQOS_MAX_COS 16 /** 16 x COS */ #define PQOS_MAX_L3CA_COS PQOS_MAX_COS #define PQOS_MAX_L2CA_COS PQOS_MAX_COS /* * ======================================= * Return values * ======================================= */ #define PQOS_RETVAL_OK 0 /**< everything OK */ #define PQOS_RETVAL_ERROR 1 /**< generic error */ #define PQOS_RETVAL_PARAM 2 /**< parameter error */ #define PQOS_RETVAL_RESOURCE 3 /**< resource error */ #define PQOS_RETVAL_INIT 4 /**< initialization error */ #define PQOS_RETVAL_TRANSPORT 5 /**< transport error */ #define PQOS_RETVAL_PERF_CTR 6 /**< performance counter error */ #define PQOS_RETVAL_BUSY 7 /**< resource busy error */ #define PQOS_RETVAL_INTER 8 /**< Interface not supported */ /* * ======================================= * Interface values * ======================================= */ enum pqos_interface { PQOS_INTER_MSR = 0, /**< MSR */ PQOS_INTER_OS = 1, /**< OS */ PQOS_INTER_OS_RESCTRL_MON = 2 /**< OS with resctrl monitoring */ }; /* * ======================================= * Init and fini * ======================================= */ enum pqos_cdp_config { PQOS_REQUIRE_CDP_OFF = 0, /**< app not compatible with CDP */ PQOS_REQUIRE_CDP_ON, /**< app requires CDP */ PQOS_REQUIRE_CDP_ANY /**< app will work with any CDP setting */ }; /** * Resource Monitoring ID (RMID) definition */ typedef uint32_t pqos_rmid_t; #ifdef PQOS_RMID_CUSTOM /** * RMID initialization types */ enum pqos_rmid_type { PQOS_RMID_TYPE_DEFAULT = 0, /**< Default sequential init */ PQOS_RMID_TYPE_MAP /**< Custom Core to RMID mapping */ }; /** * RMID configuration */ struct pqos_rmid_config { enum pqos_rmid_type type; /**< rmid initialization type */ struct { unsigned num; /**< number of rmid to core mappings */ pqos_rmid_t *rmid; /**< rmid table */ unsigned *core; /**< core table */ } map; }; #endif /** * PQoS library configuration structure * * @param fd_log file descriptor to be used as library log * @param callback_log pointer to an application callback function * void * - An application context - it can point to a structure * or an object that an application may find useful * when receiving the callback * const size_t - the size of the log message * const char * - the log message * @param context_log application specific data that is provided * to the callback function. It can be NULL if application * doesn't require it. * @param verbose logging options * LOG_VER_SILENT - no messages * LOG_VER_DEFAULT - warning and error messages * LOG_VER_VERBOSE - warning, error and info messages * LOG_VER_SUPER_VERBOSE - warning, error, info and debug messages * * @param interface preference * PQOS_INTER_MSR - MSR interface or nothing * PQOS_INTER_OS - OS interface or nothing * PQOS_INTER_OS_RESCTRL_MON - OS interface with resctrl monitoring * or nothing */ struct pqos_config { int fd_log; void (*callback_log)(void *context, const size_t size, const char *message); void *context_log; int verbose; enum pqos_interface interface; #ifdef PQOS_RMID_CUSTOM struct pqos_rmid_config rmid_cfg; #endif }; /** * @brief Initializes PQoS module * * @param [in] config initialization parameters structure * Note that fd_log in \a config needs to be a valid * file descriptor. * * @return Operation status * @retval PQOS_RETVAL_OK on success * @note If you require system wide interface enforcement you can do so by * setting the "RDT_IFACE" environment variable. */ int pqos_init(const struct pqos_config *config); /** * @brief Shuts down PQoS module * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_fini(void); /* * ======================================= * Query capabilities * ======================================= */ /** * Types of possible PQoS capabilities * * For now there are: * - monitoring capability * - L3 cache allocation capability * - L2 cache allocation capability * - Memory Bandwidth Allocation */ enum pqos_cap_type { PQOS_CAP_TYPE_MON = 0, /**< QoS monitoring */ PQOS_CAP_TYPE_L3CA, /**< L3/LLC cache allocation */ PQOS_CAP_TYPE_L2CA, /**< L2 cache allocation */ PQOS_CAP_TYPE_MBA, /**< Memory Bandwidth Allocation */ PQOS_CAP_TYPE_NUMOF }; /** * L3 Cache Allocation (CA) capability structure */ struct pqos_cap_l3ca { unsigned mem_size; /**< byte size of the structure */ unsigned num_classes; /**< number of classes of service */ unsigned num_ways; /**< number of cache ways */ unsigned way_size; /**< way size in bytes */ uint64_t way_contention; /**< ways contention bit mask */ int cdp; /**< code data prioritization feature support */ int cdp_on; /**< code data prioritization on or off */ }; /** * L2 Cache Allocation (CA) capability structure */ struct pqos_cap_l2ca { unsigned mem_size; /**< byte size of the structure */ unsigned num_classes; /**< number of classes of service */ unsigned num_ways; /**< number of cache ways */ unsigned way_size; /**< way size in bytes */ uint64_t way_contention; /**< ways contention bit mask */ int cdp; /**< code data prioritization feature support */ int cdp_on; /**< code data prioritization on or off */ }; /** * Memory Bandwidth Allocation configuration enumeration */ enum pqos_mba_config { PQOS_MBA_ANY, /**< currently enabled configuration */ PQOS_MBA_DEFAULT, /**< direct MBA hardware configuration (percentage) */ PQOS_MBA_CTRL /**< MBA controller configuration (MBps) */ }; /** * Memory Bandwidth Allocation capability structure */ struct pqos_cap_mba { unsigned mem_size; /**< byte size of the structure */ unsigned num_classes; /**< number of classes of service */ unsigned throttle_max; /**< the max MBA can be throttled */ unsigned throttle_step; /**< MBA granularity */ int is_linear; /**< the type of MBA linear/nonlinear */ int ctrl; /**< MBA controller support */ int ctrl_on; /**< MBA controller enabled */ }; /** * Available types of monitored events * (matches CPUID enumeration) */ enum pqos_mon_event { PQOS_MON_EVENT_L3_OCCUP = 1, /**< LLC occupancy event */ PQOS_MON_EVENT_LMEM_BW = 2, /**< Local memory bandwidth */ PQOS_MON_EVENT_TMEM_BW = 4, /**< Total memory bandwidth */ PQOS_MON_EVENT_RMEM_BW = 8, /**< Remote memory bandwidth (virtual event) */ RESERVED1 = 0x1000, RESERVED2 = 0x2000, PQOS_PERF_EVENT_LLC_MISS = 0x4000, /**< LLC misses */ PQOS_PERF_EVENT_IPC = 0x8000, /**< instructions per clock */ }; /** * Monitoring capabilities structure * * Few assumptions here: * - Data associated with each type of event won't exceed 64bits * This results from MSR register size. * - Interpretation of the data is up to application based * on available documentation. * - Meaning of the event is well understood by an application * based on available documentation */ struct pqos_monitor { enum pqos_mon_event type; /**< event type */ unsigned max_rmid; /**< max RMID supported for this event */ uint32_t scale_factor; /**< factor to scale RMID value to bytes */ unsigned counter_length; /**< counter bit length */ }; struct pqos_cap_mon { unsigned mem_size; /**< byte size of the structure */ unsigned max_rmid; /**< max RMID supported by socket */ unsigned l3_size; /**< L3 cache size in bytes */ unsigned num_events; /**< number of supported events */ struct pqos_monitor events[0]; }; /** * Single PQoS capabilities entry structure. * Effectively a union of all possible PQoS structures plus type. */ struct pqos_capability { enum pqos_cap_type type; union { struct pqos_cap_mon *mon; struct pqos_cap_l3ca *l3ca; struct pqos_cap_l2ca *l2ca; struct pqos_cap_mba *mba; void *generic_ptr; } u; }; /** * Structure describing all Platform QoS capabilities */ struct pqos_cap { unsigned mem_size; /**< byte size of the structure */ unsigned version; /**< version of PQoS library */ unsigned num_cap; /**< number of capabilities */ struct pqos_capability capabilities[0]; }; /** * Core information structure */ struct pqos_coreinfo { unsigned lcore; /**< logical core id */ unsigned socket; /**< socket id in the system */ unsigned l3_id; /**< L3/LLC cluster id */ unsigned l2_id; /**< L2 cluster id */ unsigned l3cat_id; /**< L3 CAT classes id */ unsigned mba_id; /**< MBA id */ }; /** * CPU cache information structure */ struct pqos_cacheinfo { int detected; /**< Indicates cache detected & valid */ unsigned num_ways; /**< Number of cache ways */ unsigned num_sets; /**< Number of sets */ unsigned num_partitions; /**< Number of partitions */ unsigned line_size; /**< Cache line size in bytes */ unsigned total_size; /**< Total cache size in bytes */ unsigned way_size; /**< Cache way size in bytes */ }; /** * ======================================= * Vendor values * ======================================= */ enum pqos_vendor { PQOS_VENDOR_UNKNOWN = 0, /**< UNKNOWN */ PQOS_VENDOR_INTEL = 1, /**< INTEL */ PQOS_VENDOR_AMD = 2 /**< AMD */ }; /** * CPU topology structure */ struct pqos_cpuinfo { unsigned mem_size; /**< byte size of the structure */ struct pqos_cacheinfo l2; /**< L2 cache information */ struct pqos_cacheinfo l3; /**< L3 cache information */ enum pqos_vendor vendor; /**< vendor Intel/AMD */ unsigned num_cores; /**< number of cores in the system */ struct pqos_coreinfo cores[0]; }; /** * @brief Retrieves PQoS capabilities data * * @param [out] cap location to store PQoS capabilities information at * @param [out] cpu location to store CPU information at * This parameter is optional and when NULL is passed then * no cpu information is returned. * CPU information includes data about number of sockets, * logical cores and their assignment. * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_cap_get(const struct pqos_cap **cap, const struct pqos_cpuinfo **cpu); /* * ======================================= * Monitoring * ======================================= */ /** * The structure to store monitoring data for all of the events */ struct pqos_event_values { uint64_t llc; /**< cache occupancy */ uint64_t mbm_local; /**< bandwidth local - reading */ uint64_t mbm_total; /**< bandwidth total - reading */ uint64_t mbm_remote; /**< bandwidth remote - reading */ uint64_t mbm_local_delta; /**< bandwidth local - delta */ uint64_t mbm_total_delta; /**< bandwidth total - delta */ uint64_t mbm_remote_delta; /**< bandwidth remote - delta */ uint64_t ipc_retired; /**< instructions retired - reading */ uint64_t ipc_retired_delta; /**< instructions retired - delta */ uint64_t ipc_unhalted; /**< unhalted cycles - reading */ uint64_t ipc_unhalted_delta; /**< unhalted cycles - delta */ double ipc; /**< retired instructions / cycles */ uint64_t llc_misses; /**< LLC misses - reading */ uint64_t llc_misses_delta; /**< LLC misses - delta */ }; struct pqos_mon_data_internal; /** * Monitoring group data structure */ struct pqos_mon_data { /** * Common section */ int valid; /**< structure validity marker */ enum pqos_mon_event event; /**< monitored event */ void *context; /**< application specific context pointer */ struct pqos_event_values values; /**< RMID events value */ /** * Task specific section */ unsigned num_pids; /**< number of pids in the group */ pid_t *pids; /**< list of pids in the group */ unsigned tid_nr; pid_t *tid_map; /** * Core specific section */ unsigned *cores; /**< list of cores in the group */ unsigned num_cores; /**< number of cores in the group */ struct pqos_mon_data_internal *intl; /**< internal data */ }; /** * @brief Resets monitoring by binding all cores with RMID0 * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_reset(void); /** * @brief Reads RMID association of the \a lcore * * @param [in] lcore CPU logical core id * @param [out] rmid place to store resource monitoring id * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_assoc_get(const unsigned lcore, pqos_rmid_t *rmid); /** * @brief Starts resource monitoring on selected group of cores * * The function sets up content of the \a group structure. * * Note that \a event cannot select PQOS_PERF_EVENT_IPC or * PQOS_PERF_EVENT_L3_MISS events without any PQoS event * selected at the same time. * * @param [in] num_cores number of cores in \a cores array * @param [in] cores array of logical core id's * @param [in] event combination of monitoring events * @param [in] context a pointer for application's convenience * (unused by the library) * @param [in,out] group a pointer to monitoring structure * * @return Operations status * @retval PQOS_RETVAL_OK on success * * @note As of Kernel 4.10, Intel(R) RDT perf results per core are found to * be incorrect. */ int pqos_mon_start(const unsigned num_cores, const unsigned *cores, const enum pqos_mon_event event, void *context, struct pqos_mon_data *group); /** * @brief Starts resource monitoring of selected \a pid (process) * * @param [in] pid process ID * @param [in] event monitoring event id * @param [in] context a pointer for application's convenience * (unused by the library) * @param [in,out] group a pointer to monitoring structure * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_start_pid(const pid_t pid, const enum pqos_mon_event event, void *context, struct pqos_mon_data *group); /** * @brief Starts resource monitoring of selected \a pids (processes) * * @param [in] num_pids number of pids in \a pids array * @param [in] pids array of process ID * @param [in] event monitoring event id * @param [in] context a pointer for application's convenience * (unused by the library) * @param [in,out] group a pointer to monitoring structure * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_start_pids(const unsigned num_pids, const pid_t *pids, const enum pqos_mon_event event, void *context, struct pqos_mon_data *group); /** * @brief Adds pids to the resource monitoring grpup * * @param [in] num_pids number of pids in \a pids array * @param [in] pids array of process ID * @param [in,out] group a pointer to monitoring structure * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_add_pids(const unsigned num_pids, const pid_t *pids, struct pqos_mon_data *group); /** * @brief Remove pids from the resource monitoring grpup * * @param [in] num_pids number of pids in \a pids array * @param [in] pids array of process ID * @param [in,out] group a pointer to monitoring structure * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_remove_pids(const unsigned num_pids, const pid_t *pids, struct pqos_mon_data *group); /** * @brief Stops resource monitoring data for selected monitoring group * * @param [in] group monitoring context for selected number of cores * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_stop(struct pqos_mon_data *group); /** * @brief Polls monitoring data from requested cores * * @param [in] groups table of monitoring group pointers to be be updated * @param [in] num_groups number of monitoring groups in the table * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mon_poll(struct pqos_mon_data **groups, const unsigned num_groups); /* * ======================================= * Allocation Technology * ======================================= */ /** * @brief Associates \a lcore with given class of service * * @param [in] lcore CPU logical core id * @param [in] class_id class of service * * @return Operations status */ int pqos_alloc_assoc_set(const unsigned lcore, const unsigned class_id); /** * @brief Reads association of \a lcore with class of service * * @param [in] lcore CPU logical core id * @param [out] class_id class of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_alloc_assoc_get(const unsigned lcore, unsigned *class_id); /** * @brief OS interface to associate \a task * with given class of service * * @param [in] task task ID to be associated * @param [in] class_id class of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_alloc_assoc_set_pid(const pid_t task, const unsigned class_id); /** * @brief OS interface to read association * of \a task with class of service * * @param [in] task ID to find association * @param [out] class_id class of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_alloc_assoc_get_pid(const pid_t task, unsigned *class_id); /** * @brief Assign first available COS to cores in \a core_array * * While searching for available COS take technologies it is intended to use * with into account. * Note on \a technology and \a core_array selection: * - if L2 CAT technology is requested then cores need to belong to * one L2 cluster (same L2ID) * - if only L3 CAT is requested then cores need to belong to one socket * - if only MBA is selected then cores need to belong to one socket * * @param [in] technology bit mask selecting technologies * (1 << enum pqos_cap_type) * @param [in] core_array list of core ids * @param [in] core_num number of core ids in the \a core_array * @param [out] class_id place to store reserved COS id * * @return Operations status */ int pqos_alloc_assign(const unsigned technology, const unsigned *core_array, const unsigned core_num, unsigned *class_id); /** * @brief Reassign cores in \a core_array to default COS#0 * * @param [in] core_array list of core ids * @param [in] core_num number of core ids in the \a core_array * * @return Operations status */ int pqos_alloc_release(const unsigned *core_array, const unsigned core_num); /** * @brief Assign first available COS to tasks in \a task_array * Searches all COS directories from highest to lowest * * While searching for available COS take technologies it is intended to use * with into account. * Note on \a technology parameter: * - this parameter is currently reserved for future use * - resctrl (Linux interface) will only provide the highest class id common * to all supported technologies * * @param [in] technology bit mask selecting technologies * (1 << enum pqos_cap_type) * @param [in] task_array list of task ids * @param [in] task_num number of task ids in the \a task_array * @param [out] class_id place to store reserved COS id * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_alloc_assign_pid(const unsigned technology, const pid_t *task_array, const unsigned task_num, unsigned *class_id); /** * @brief Reassign tasks in \a task_array to default COS#0 * * @param [in] task_array list of task ids * @param [in] task_num number of task ids in the \a task_array * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_alloc_release_pid(const pid_t *task_array, const unsigned task_num); /** * @brief Resets configuration of allocation technologies * * Reverts CAT/MBA state to the one after reset: * - all cores associated with COS0 * - all COS are set to give access to entire resource * * As part of allocation reset CDP reconfiguration can be performed. * This can be requested via \a l3_cdp_cfg, \a l2_cdp_cfg and \a mba_cfg. * * @param [in] l3_cdp_cfg requested L3 CAT CDP config * @param [in] l2_cdp_cfg requested L2 CAT CDP config * @param [in] mba_cfg requested MBA config * * @return Operation status * @retval PQOS_RETVAL_OK on success */ 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); /* * ======================================= * L3 cache allocation * ======================================= */ /** * L3 cache allocation class of service data structure */ struct pqos_l3ca { unsigned class_id; /**< class of service */ int cdp; /**< data & code masks used if true */ union { uint64_t ways_mask; /**< bit mask for L3 cache ways */ struct { uint64_t data_mask; uint64_t code_mask; } s; } u; }; /** * @brief Sets classes of service defined by \a ca on \a l3cat_id * * @param [in] l3cat_id L3 CAT resource id * @param [in] num_cos number of classes of service at \a ca * @param [in] ca table with class of service definitions * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_l3ca_set(const unsigned l3cat_id, const unsigned num_cos, const struct pqos_l3ca *ca); /** * @brief Reads classes of service from \a socket * * @param [in] l3cat_id L3 CAT resource id * @param [in] max_num_ca maximum number of classes of service * that can be accommodated at \a ca * @param [out] num_ca number of classes of service read into \a ca * @param [out] ca table with read classes of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_l3ca_get(const unsigned l3cat_id, const unsigned max_num_ca, unsigned *num_ca, struct pqos_l3ca *ca); /** * @brief Get minimum number of bits which must be set in L3 way mask when * updating a class of service * * @param [out] min_cbm_bits minimum number of bits that must be set * * @return Operational status * @retval PQOS_RETVAL_OK on success * @retval PQOS_RETVAL_RESOURCE if unable to determine */ int pqos_l3ca_get_min_cbm_bits(unsigned *min_cbm_bits); /* * ======================================= * L2 cache allocation * ======================================= */ /** * L2 cache allocation class of service data structure */ struct pqos_l2ca { unsigned class_id; /**< class of service */ int cdp; /**< data & code masks used if true */ union { uint64_t ways_mask; /**< bit mask for L2 cache ways */ struct { uint64_t data_mask; uint64_t code_mask; } s; } u; }; /** * @brief Sets classes of service defined by \a ca on \a l2id * * @param [in] l2id unique L2 cache identifier * @param [in] num_cos number of classes of service at \a ca * @param [in] ca table with class of service definitions * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_l2ca_set(const unsigned l2id, const unsigned num_cos, const struct pqos_l2ca *ca); /** * @brief Reads classes of service from \a l2id * * @param [in] l2id unique L2 cache identifier * @param [in] max_num_ca maximum number of classes of service * that can be accommodated at \a ca * @param [out] num_ca number of classes of service read into \a ca * @param [out] ca table with read classes of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_l2ca_get(const unsigned l2id, const unsigned max_num_ca, unsigned *num_ca, struct pqos_l2ca *ca); /** * @brief Get minimum number of bits which must be set in L2 way mask when * updating a class of service * * @param [out] min_cbm_bits minimum number of bits that must be set * * @return Operational status * @retval PQOS_RETVAL_OK on success * @retval PQOS_RETVAL_RESOURCE if unable to determine */ int pqos_l2ca_get_min_cbm_bits(unsigned *min_cbm_bits); /* * ======================================= * Memory Bandwidth Allocation * ======================================= */ /** * MBA class of service data structure */ struct pqos_mba { unsigned class_id; /**< class of service */ unsigned mb_max; /**< maximum available bandwidth in percentage (without MBA controller) or in MBps (with MBA controller), depending on ctrl flag */ int ctrl; /**< MBA controller flag */ }; /** * @brief Sets classes of service defined by \a mba on \a mba id * * @param [in] mba_id MBA resource 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 */ int pqos_mba_set(const unsigned mba_id, const unsigned num_cos, const struct pqos_mba *requested, struct pqos_mba *actual); /** * @brief Reads MBA from \a mba_id * * @param [in] mba_id MBA resource id * @param [in] max_num_cos maximum number of classes of service * that can be accommodated at \a mba_tab * @param [out] num_cos number of classes of service read into \a mba_tab * @param [out] mba_tab table with read classes of service * * @return Operations status * @retval PQOS_RETVAL_OK on success */ int pqos_mba_get(const unsigned mba_id, const unsigned max_num_cos, unsigned *num_cos, struct pqos_mba *mba_tab); /* * ======================================= * Utility API * ======================================= */ /** * @brief Retrieves mba id's from cpu info structure * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [out] count place to store actual number of mba ids returned * * @return Allocated array of size \a count populated with mba id's * @retval NULL on error */ unsigned *pqos_cpu_get_mba_ids(const struct pqos_cpuinfo *cpu, unsigned *count); /** * @brief Retrieves l3cat id's from cpu info structure * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [out] count place to store actual number of l3cat ids returned * * @return Allocated array of size \a count populated with l3cat id's * @retval NULL on error */ unsigned *pqos_cpu_get_l3cat_ids(const struct pqos_cpuinfo *cpu, unsigned *count); /** * @brief Retrieves socket id's from cpu info structure * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [out] count place to store actual number of sockets returned * * @return Allocated array of size \a count populated with socket id's * @retval NULL on error */ unsigned *pqos_cpu_get_sockets(const struct pqos_cpuinfo *cpu, unsigned *count); /** * @brief Retrieves L2 id's from cpu info structure * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [out] count place to store actual number of L2 id's returned * * @return Allocated array of size \a count populated with L2 id's * @retval NULL on error */ unsigned *pqos_cpu_get_l2ids(const struct pqos_cpuinfo *cpu, unsigned *count); /** * @brief Creates list of cores belonging to given L3 cluster * * Function allocates memory for the core list that needs to be freed by * the caller. * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] l3_id L3 cluster ID * @param [out] count place to put number of cores found * * @return Pointer to list of cores belonging to the L3 cluster * @retval NULL on error or if no core found */ unsigned *pqos_cpu_get_cores_l3id(const struct pqos_cpuinfo *cpu, const unsigned l3_id, unsigned *count); /** * @brief Retrieves core id's from cpu info structure for \a socket * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] socket CPU socket id to enumerate * @param [out] count place to store actual number of core id's returned * * @return Allocated core id array * @retval NULL on error */ unsigned *pqos_cpu_get_cores(const struct pqos_cpuinfo *cpu, const unsigned socket, unsigned *count); /** * @brief Retrieves core id's from cpu info structure for \a l3cat_id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] l3cat_id to enumerate * @param [out] count place to store actual number of core id's returned * * @return Allocated core id array * @retval NULL on error */ unsigned *pqos_cpu_get_cores_l3cat_id(const struct pqos_cpuinfo *cpu, const unsigned l3cat_id, unsigned *count); /** * @brief Retrieves task id's from resctrl task file for a given COS * * @param [in] class_id Class of Service ID * @param [out] count place to store actual number of task id's returned * * @return Allocated task id array * @retval NULL on error */ unsigned *pqos_pid_get_pid_assoc(const unsigned class_id, unsigned *count); /** * @brief Retrieves one core id from cpu info structure for \a mba_id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] mba to enumerate * @param [out] lcore place to store returned core id * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_one_by_mba_id(const struct pqos_cpuinfo *cpu, const unsigned mba_id, unsigned *lcore); /** * @brief Retrieves core information from cpu info structure for \a lcore * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] lcore logical core ID to retrieve information for * * @return Pointer to core information structure * @retval NULL on error */ const struct pqos_coreinfo * pqos_cpu_get_core_info(const struct pqos_cpuinfo *cpu, unsigned lcore); /** * @brief Retrieves one core id from cpu info structure for \a socket * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] socket CPU socket id to enumerate * @param [out] lcore place to store returned core id * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_one_core(const struct pqos_cpuinfo *cpu, const unsigned socket, unsigned *lcore); /** * @brief Retrieves one core id from cpu info structure for \a l3cat id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] l3cat id to enumerate * @param [out] lcore place to store returned core id * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_one_by_l3cat_id(const struct pqos_cpuinfo *cpu, const unsigned l3cat_id, unsigned *lcore); /** * @brief Retrieves one core id from cpu info structure for \a l2id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] l2id unique L2 cache identifier * @param [out] lcore place to store returned core id * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_one_by_l2id(const struct pqos_cpuinfo *cpu, const unsigned l2id, unsigned *lcore); /** * @brief Verifies if \a core is a valid logical core id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] lcore logical core id * * @return Operation status * @retval PQOS_RETVAL_OK on success (\a lcore is valid) */ int pqos_cpu_check_core(const struct pqos_cpuinfo *cpu, const unsigned lcore); /** * @brief Retrieves socket id for given logical core id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] lcore logical core id * @param [out] socket location to store socket id at * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_socketid(const struct pqos_cpuinfo *cpu, const unsigned lcore, unsigned *socket); /** * @brief Retrieves monitoring cluster id for given logical core id * * @param [in] cpu CPU information structure from \a pqos_cap_get * @param [in] lcore logical core id * @param [out] cluster location to store cluster id at * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cpu_get_clusterid(const struct pqos_cpuinfo *cpu, const unsigned lcore, unsigned *cluster); /** * @brief Retrieves \a type of capability from \a cap structure * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [in] type capability type to look for * @param [out] cap_item place to store pointer to selected capability * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cap_get_type(const struct pqos_cap *cap, const enum pqos_cap_type type, const struct pqos_capability **cap_item); /** * @brief Retrieves \a monitoring event data from \a cap structure * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [in] event monitoring event type to look for * @param [out] p_mon place to store pointer to selected event capabilities * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_cap_get_event(const struct pqos_cap *cap, const enum pqos_mon_event event, const struct pqos_monitor **p_mon); /** * @brief Retrieves number of L3 allocation classes of service from * \a cap structure. * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] cos_num place to store number of classes of service * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_l3ca_get_cos_num(const struct pqos_cap *cap, unsigned *cos_num); /** * @brief Retrieves number of L2 allocation classes of service from * \a cap structure. * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] cos_num place to store number of classes of service * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_l2ca_get_cos_num(const struct pqos_cap *cap, unsigned *cos_num); /** * @brief Retrieves number of memory B/W allocation classes of service from * \a cap structure. * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] cos_num place to store number of classes of service * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_mba_get_cos_num(const struct pqos_cap *cap, unsigned *cos_num); /** * @brief Retrieves L3 CDP status * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] cdp_supported place to store L3 CDP support status * @param [out] cdp_enabled place to store L3 CDP enable status * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_l3ca_cdp_enabled(const struct pqos_cap *cap, int *cdp_supported, int *cdp_enabled); /** * @brief Retrieves L2 CDP status * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] cdp_supported place to store L2 CDP support status * @param [out] cdp_enabled place to store L2 CDP enable status * * @return Operation status * @retval PQOS_RETVAL_OK on success */ int pqos_l2ca_cdp_enabled(const struct pqos_cap *cap, int *cdp_supported, int *cdp_enabled); /** * @brief Retrieves MBA controller configuration status * * @param [in] cap platform QoS capabilities structure * returned by \a pqos_cap_get * @param [out] ctrl_supported place to store MBA controller support status * @param [out] ctrl_enabled place to store MBA controller enable status * */ int pqos_mba_ctrl_enabled(const struct pqos_cap *cap, int *ctrl_supported, int *ctrl_enabled); /** * @brief returns the CPU vendor identification * * @param [in] cpu CPU information structure from \a pqos_cap_get * @retval 0 if vendor unknown * @return 1 if the vendor is Intel * @return 2 if the vendor is AMD */ enum pqos_vendor pqos_get_vendor(const struct pqos_cpuinfo *cpu); /** * @brief Retrieves a monitoring value from a group for a specific event. * @param [out] value monitoring value * @param [in] event_id event being monitored * @param [in] group monitoring group * * @return Operation status * @retval PQOS_RETVAL_OK on success */ static inline int pqos_mon_get_event_value(void *const value, const enum pqos_mon_event event_id, const struct pqos_mon_data *const group) { uint64_t *const p_64 = (uint64_t *)value; double *const p_dbl = (double *)value; if (group == NULL || value == NULL) return PQOS_RETVAL_PARAM; switch (event_id) { case PQOS_MON_EVENT_L3_OCCUP: *p_64 = group->values.llc; break; case PQOS_MON_EVENT_LMEM_BW: *p_64 = group->values.mbm_local_delta; break; case PQOS_MON_EVENT_TMEM_BW: *p_64 = group->values.mbm_total_delta; break; case PQOS_MON_EVENT_RMEM_BW: *p_64 = group->values.mbm_remote_delta; break; case PQOS_PERF_EVENT_IPC: *p_dbl = group->values.ipc; break; case PQOS_PERF_EVENT_LLC_MISS: *p_64 = group->values.llc_misses_delta; break; default: return PQOS_RETVAL_PARAM; } return PQOS_RETVAL_OK; } #ifdef __cplusplus } #endif #endif /* __PQOS_H__ */