/** * @brief Prints information about cache allocation settings in the system * * @param sock_count number of detected CPU sockets * @param sockets arrays with detected CPU socket id's * @param cpu_info cpu information structure */ static void print_allocation_config(const struct pqos_capability *cap_l3ca, const unsigned sock_count, const unsigned *sockets, const struct pqos_cpuinfo *cpu_info) { int ret; unsigned i; if (cap_l3ca == NULL) return; for (i = 0; i < sock_count; i++) { struct pqos_l3ca tab[PQOS_MAX_L3CA_COS]; unsigned num = 0; ret = pqos_l3ca_get(sockets[i], PQOS_MAX_L3CA_COS, &num, tab); if (ret == PQOS_RETVAL_OK) { unsigned n = 0; printf("L3CA COS definitions for Socket %u:\n", sockets[i]); for (n = 0; n < num; n++) { printf(" L3CA COS%u => MASK 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].u.ways_mask); } } } for (i = 0; i < sock_count; i++) { unsigned *lcores = NULL; unsigned lcount = 0, n = 0; lcores = pqos_cpu_get_cores(cpu_info, sockets[i], &lcount); if (lcores == NULL || lcount == 0) { printf("Error retrieving core information!\n"); free(lcores); return; } printf("Core information for socket %u:\n", sockets[i]); for (n = 0; n < lcount; n++) { unsigned class_id = 0; int ret1 = PQOS_RETVAL_OK; if (cap_l3ca != NULL) ret1 = pqos_alloc_assoc_get(lcores[n], &class_id); if (ret1 == PQOS_RETVAL_OK) printf(" Core %u => COS%u\n", lcores[n], class_id); else printf(" Core %u => ERROR\n", lcores[n]); } free(lcores); } }
/** * @brief Prints information about cache allocation settings in the system */ static void print_allocation_config(void) { int ret; unsigned i; unsigned sock_count, *sockets = NULL; const struct pqos_cpuinfo *p_cpu = NULL; const struct pqos_cap *p_cap = NULL; /* Get CMT capability and CPU info pointer */ ret = pqos_cap_get(&p_cap, &p_cpu); if (ret != PQOS_RETVAL_OK) { printf("Error retrieving PQoS capabilities!\n"); return; } /* Get CPU socket information to set COS */ sockets = pqos_cpu_get_sockets(p_cpu, &sock_count); if (sockets == NULL) { printf("Error retrieving CPU socket information!\n"); return; } for (i = 0; i < sock_count; i++) { unsigned *lcores = NULL; unsigned lcount = 0, n = 0; lcores = pqos_cpu_get_cores(p_cpu, sockets[i], &lcount); if (lcores == NULL || lcount == 0) { printf("Error retrieving core information!\n"); free(sockets); return; } printf("Core information for socket %u:\n", sockets[i]); for (n = 0; n < lcount; n++) { unsigned class_id = 0; ret = pqos_alloc_assoc_get(lcores[n], &class_id); if (ret == PQOS_RETVAL_OK) printf(" Core %u => COS%u\n", lcores[n], class_id); else printf(" Core %u => ERROR\n", lcores[n]); } free(lcores); } free(sockets); }
int pqos_l2ca_get(const unsigned socket, const unsigned max_num_ca, unsigned *num_ca, struct pqos_l2ca *ca) { int ret = PQOS_RETVAL_OK; unsigned i = 0, count = 0; unsigned core = 0, core_count = 0; _pqos_api_lock(); ret = _pqos_check_init(1); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (num_ca == NULL || ca == NULL || max_num_ca == 0) { _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } ASSERT(m_cap != NULL); ret = pqos_l2ca_get_cos_num(m_cap, &count); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_RESOURCE; /* L2 CAT not supported */ } if (max_num_ca < count) { /* Not enough space to store the classes */ _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } ASSERT(m_cpu != NULL); ret = pqos_cpu_get_cores(m_cpu, socket, 1, &core_count, &core); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } ASSERT(core_count > 0); for (i = 0; i < count; i++) { uint32_t reg = PQOS_MSR_L2CA_MASK_START + i; uint64_t val = 0; int retval = msr_read(core, reg, &val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ca[i].class_id = i; ca[i].ways_mask = val; } *num_ca = count; _pqos_api_unlock(); return ret; }
int pqos_l2ca_set(const unsigned socket, const unsigned num_ca, const struct pqos_l2ca *ca) { int ret = PQOS_RETVAL_OK; unsigned i = 0, count = 0, core = 0; _pqos_api_lock(); ret = _pqos_check_init(1); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (ca == NULL || num_ca == 0) { _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } /** * Check if L2 CAT is supported */ ASSERT(m_cap != NULL); ret = pqos_l2ca_get_cos_num(m_cap, &count); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_RESOURCE; /* L2 CAT not supported */ } /** * Check if class bitmasks are contiguous and * if class id's are within allowed range. */ for (i = 0; i < num_ca; i++) { if (!is_contiguous(ca[i].ways_mask)) { LOG_ERROR("L2 COS%u bit mask is not contiguous!\n", ca[i].class_id); _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } if (ca[i].class_id >= count) { LOG_ERROR("L2 COS%u is out of range (COS%u is max)!\n", ca[i].class_id, count - 1); _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } } /** * Pick one core from the socket and * perfrom MSR writes to COS registers on the socket. */ ASSERT(m_cpu != NULL); ret = pqos_cpu_get_cores(m_cpu, socket, 1, &count, &core); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } for (i = 0; i < num_ca; i++) { uint32_t reg = ca[i].class_id + PQOS_MSR_L2CA_MASK_START; uint64_t val = ca[i].ways_mask; int retval = MACHINE_RETVAL_OK; retval = msr_write(core, reg, val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } } _pqos_api_unlock(); return ret; }
int pqos_l3ca_get(const unsigned socket, const unsigned max_num_ca, unsigned *num_ca, struct pqos_l3ca *ca) { int ret = PQOS_RETVAL_OK; unsigned i = 0, count = 0, core = 0, core_count = 0; uint32_t reg = 0; uint64_t val = 0; int retval = MACHINE_RETVAL_OK; int cdp_enabled = 0; _pqos_api_lock(); ret = _pqos_check_init(1); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (num_ca == NULL || ca == NULL || max_num_ca == 0) { _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } ASSERT(m_cap != NULL); ret = pqos_l3ca_get_cos_num(m_cap, &count); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; /**< perhaps no L3CA capability */ } ret = pqos_l3ca_cdp_enabled(m_cap, NULL, &cdp_enabled); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (count > max_num_ca) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ASSERT(m_cpu != NULL); ret = pqos_cpu_get_cores(m_cpu, socket, 1, &core_count, &core); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } ASSERT(core_count > 0); if (cdp_enabled) { for (i = 0, reg = PQOS_MSR_L3CA_MASK_START; i < count; i++, reg += 2) { ca[i].cdp = 1; ca[i].class_id = i; retval = msr_read(core, reg, &val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ca[i].u.s.data_mask = val; retval = msr_read(core, reg+1, &val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ca[i].u.s.code_mask = val; } } else { for (i = 0, reg = PQOS_MSR_L3CA_MASK_START; i < count; i++, reg++) { retval = msr_read(core, reg, &val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ca[i].cdp = 0; ca[i].class_id = i; ca[i].u.ways_mask = val; } } *num_ca = count; _pqos_api_unlock(); return ret; }
int pqos_l3ca_set(const unsigned socket, const unsigned num_ca, const struct pqos_l3ca *ca) { int ret = PQOS_RETVAL_OK; unsigned i = 0, count = 0, core = 0; int cdp_enabled = 0; _pqos_api_lock(); ret = _pqos_check_init(1); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (ca == NULL || num_ca == 0) { _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } /** * Check if class bitmasks are contiguous. */ for (i = 0; i < num_ca; i++) { int is_contig = 0; if (ca[i].cdp) { is_contig = is_contiguous(ca[i].u.s.data_mask) && is_contiguous(ca[i].u.s.code_mask); } else { is_contig = is_contiguous(ca[i].u.ways_mask); } if (!is_contig) { LOG_ERROR("L3 COS%u bit mask is not contiguous!\n", ca[i].class_id); _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } } ASSERT(m_cap != NULL); ret = pqos_l3ca_get_cos_num(m_cap, &count); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; /**< perhaps no L3CA capability */ } if (num_ca > count) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } ret = pqos_l3ca_cdp_enabled(m_cap, NULL, &cdp_enabled); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } ASSERT(m_cpu != NULL); ret = pqos_cpu_get_cores(m_cpu, socket, 1, &count, &core); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } if (cdp_enabled) { for (i = 0; i < num_ca; i++) { uint32_t reg = (ca[i].class_id*2) + PQOS_MSR_L3CA_MASK_START; int retval = MACHINE_RETVAL_OK; uint64_t cmask = 0, dmask = 0; if (ca[i].cdp) { dmask = ca[i].u.s.data_mask; cmask = ca[i].u.s.code_mask; } else { dmask = ca[i].u.ways_mask; cmask = ca[i].u.ways_mask; } retval = msr_write(core, reg, dmask); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } retval = msr_write(core, reg+1, cmask); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } } } else { for (i = 0; i < num_ca; i++) { uint32_t reg = ca[i].class_id + PQOS_MSR_L3CA_MASK_START; uint64_t val = ca[i].u.ways_mask; int retval = MACHINE_RETVAL_OK; if (ca[i].cdp) { LOG_ERROR("Attempting to set CDP COS " "while CDP is disabled!\n"); _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } retval = msr_write(core, reg, val); if (retval != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } } } _pqos_api_unlock(); return ret; }
void find_cos_in_use(const struct pqos_capability *cap_mon, const struct pqos_capability *cap_l3ca, const unsigned sock_count, const unsigned *sockets, const struct pqos_cpuinfo *cpu_info, int *corse_to_cos) { int ret; unsigned i; for (i = 0; (i < sock_count) && (cap_l3ca != NULL); i++) { struct pqos_l3ca tab[PQOS_MAX_L3CA_COS]; unsigned num = 0; unsigned n = 0; ret = pqos_l3ca_get(sockets[i], PQOS_MAX_L3CA_COS, &num, tab); if (ret != PQOS_RETVAL_OK) continue; printf("L3CA COS definitions for Socket %u:\n", sockets[i]); for (n = 0; n < num; n++) { if (tab[n].cdp) { printf(" L3CA COS%u => DATA 0x%llx," "CODE 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].data_mask, (unsigned long long)tab[n].code_mask); } else { printf(" L3CA COS%u => MASK 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].ways_mask); } } } for (i = 0; i < sock_count; i++) { unsigned lcores[PQOS_MAX_SOCKET_CORES]; unsigned lcount = 0, n = 0; ret = pqos_cpu_get_cores(cpu_info, sockets[i], PQOS_MAX_SOCKET_CORES, &lcount, &lcores[0]); if (ret != PQOS_RETVAL_OK) { printf("Error retrieving core information!\n"); return; } ASSERT(ret == PQOS_RETVAL_OK); printf("Core information for socket %u:\n", sockets[i]); for (n = 0; n < lcount; n++) { unsigned class_id = 0; pqos_rmid_t rmid = 0; int ret1 = PQOS_RETVAL_OK; int ret2 = PQOS_RETVAL_OK; if (cap_l3ca != NULL) ret1 = pqos_l3ca_assoc_get(lcores[n], &class_id); if (cap_mon != NULL) ret2 = pqos_mon_assoc_get(lcores[n], &rmid); if (ret1 == PQOS_RETVAL_OK && ret2 == PQOS_RETVAL_OK) { if (cap_l3ca != NULL && cap_mon != NULL) corse_to_cos[class_id] = 1; if (cap_l3ca == NULL && cap_mon != NULL) if (cap_l3ca != NULL && cap_mon == NULL) corse_to_cos[class_id] = 1; } else { printf(" Core %u => ERROR In Learning\n", lcores[n]); } } } }
void alloc_print_config(const struct pqos_capability *cap_mon, const struct pqos_capability *cap_l3ca, const struct pqos_capability *cap_l2ca, const unsigned sock_count, const unsigned *sockets, const struct pqos_cpuinfo *cpu_info) { int ret; unsigned i; for (i = 0; (i < sock_count) && (cap_l3ca != NULL); i++) { struct pqos_l3ca tab[PQOS_MAX_L3CA_COS]; unsigned num = 0; unsigned n = 0; ret = pqos_l3ca_get(sockets[i], PQOS_MAX_L3CA_COS, &num, tab); if (ret != PQOS_RETVAL_OK) continue; printf("L3CA COS definitions for Socket %u:\n", sockets[i]); for (n = 0; n < num; n++) { if (tab[n].cdp) { printf(" L3CA COS%u => DATA 0x%llx," "CODE 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].u.s.data_mask, (unsigned long long) tab[n].u.s.code_mask); } else { printf(" L3CA COS%u => MASK 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].u.ways_mask); } } } for (i = 0; (i < sock_count) && (cap_l2ca != NULL); i++) { struct pqos_l2ca tab[PQOS_MAX_L2CA_COS]; unsigned num = 0; unsigned n = 0; ret = pqos_l2ca_get(sockets[i], PQOS_MAX_L2CA_COS, &num, tab); if (ret != PQOS_RETVAL_OK) continue; printf("L2CA COS definitions for Socket %u:\n", sockets[i]); for (n = 0; n < num; n++) printf(" L2CA COS%u => MASK 0x%llx\n", tab[n].class_id, (unsigned long long)tab[n].ways_mask); } for (i = 0; i < sock_count; i++) { unsigned *lcores = NULL; unsigned lcount = 0, n = 0; lcores = pqos_cpu_get_cores(cpu_info, sockets[i], &lcount); if (lcores == NULL) { printf("Error retrieving core information!\n"); return; } printf("Core information for socket %u:\n", sockets[i]); for (n = 0; n < lcount; n++) { unsigned class_id = 0; pqos_rmid_t rmid = 0; int ret = PQOS_RETVAL_OK; const int is_mon = (cap_mon != NULL); const int is_alloc = (cap_l3ca != NULL) || (cap_l2ca != NULL); if (is_alloc) ret = pqos_alloc_assoc_get(lcores[n], &class_id); if (is_mon && ret == PQOS_RETVAL_OK) ret = pqos_mon_assoc_get(lcores[n], &rmid); if (ret != PQOS_RETVAL_OK) { printf(" Core %u => ERROR\n", lcores[n]); continue; } if (is_alloc && is_mon) printf(" Core %u => COS%u, RMID%u\n", lcores[n], class_id, (unsigned)rmid); if (is_alloc && !is_mon) printf(" Core %u => COS%u\n", lcores[n], class_id); if (!is_alloc && is_mon) printf(" Core %u => RMID%u\n", lcores[n], (unsigned)rmid); } free(lcores); } }