/** * @brief Sets L3/L2 allocation classes on a socket * * @param ca structure containing L3/L2 CAT info * @param s socket id * @return number of classes that have been set * @retval positive - number of classes set * @retval negative - error */ static int set_alloc(struct cat_cos_sock *ca, const unsigned s) { int ret, set = 0; if (s >= PQOS_MAX_SOCKETS || ca == NULL) return -1; if (ca->cos_num_l3ca) { ret = pqos_l3ca_set(s, ca->cos_num_l3ca, ca->cos_tab_l3ca); ASSERT(ret == PQOS_RETVAL_OK); if (ret != PQOS_RETVAL_OK) goto set_l3_cos_failure; set += ca->cos_num_l3ca; } if (ca->cos_num_l2ca) { ret = pqos_l2ca_set(s, ca->cos_num_l2ca, ca->cos_tab_l2ca); ASSERT(ret == PQOS_RETVAL_OK); if (ret != PQOS_RETVAL_OK) goto set_l2_cos_failure; set += ca->cos_num_l2ca; } return set; set_l3_cos_failure: printf("Setting up L3 CAT class of service failed!\n"); return -1; set_l2_cos_failure: printf("Setting up L2 CAT class of service failed!\n"); return -1; }
/** * @brief Sets up allocation classes of service on selected CPU sockets * * @param sock_count number of CPU sockets * @param sockets arrays with CPU socket id's * * @return Number of classes of service set * @retval 0 no class of service set (nor selected) * @retval negative error * @retval positive success */ static int set_allocation_class(unsigned sock_count, const unsigned *sockets) { int ret; while (sock_count > 0 && sel_l3ca_cos_num > 0) { ret = pqos_l3ca_set(*sockets, sel_l3ca_cos_num, sel_l3ca_cos_tab); if (ret != PQOS_RETVAL_OK) { printf("Setting up cache allocation class of " "service failed!\n"); return -1; } sock_count--; sockets++; } return sel_l3ca_cos_num; }
int pqos_l3ca_reset(const struct pqos_cap *cap, const struct pqos_cpuinfo *cpu) { unsigned *sockets = NULL; unsigned sockets_num = 0, sockets_num_ret = 0; const struct pqos_capability *item = NULL; int ret = PQOS_RETVAL_OK; unsigned j; ASSERT(cap != NULL && cpu != NULL); if (cap == NULL || cpu == NULL) return PQOS_RETVAL_PARAM; ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item); if (ret != PQOS_RETVAL_OK) return ret; /**< no L3CA capability */ ASSERT(item != NULL); /** * Figure out number of sockets in the system * - allocate enough memory to accommodate all socket id's * - use stack frame allocator for it (not heap) * - get list of socket id's through another API * - validate that number of socket id's obtained in * two different ways match */ sockets_num = __get_num_sockets(cpu); if (sockets_num == 0) return PQOS_RETVAL_RESOURCE; sockets = alloca(sockets_num * sizeof(sockets[0])); if (sockets == NULL) return PQOS_RETVAL_RESOURCE; ret = pqos_cpu_get_sockets(cpu, sockets_num, &sockets_num_ret, sockets); if (ret != PQOS_RETVAL_OK) return ret; ASSERT(sockets_num_ret == sockets_num); if (sockets_num != sockets_num_ret) return PQOS_RETVAL_ERROR; /** * Change COS definition on all sockets * so that each COS allows for access to all cache ways */ for (j = 0; j < sockets_num; j++) { const uint64_t ways_mask = (1ULL<<item->u.l3ca->num_ways)-1ULL; unsigned i; for (i = 0; i < item->u.l3ca->num_classes; i++) { struct pqos_l3ca cos; cos.cdp = 0; cos.class_id = i; cos.ways_mask = ways_mask; ret = pqos_l3ca_set(sockets[j], 1, &cos); if (ret != PQOS_RETVAL_OK) return ret; } } /** * Associate all cores with COS0 */ for (j = 0; j < cpu->num_cores; j++) { ret = pqos_l3ca_assoc_set(cpu->cores[j].lcore, 0); if (ret != PQOS_RETVAL_OK) return ret; } return ret; }