int hw_alloc_assoc_set(const unsigned lcore, const unsigned class_id) { int ret = PQOS_RETVAL_OK; unsigned num_l2_cos = 0, num_l3_cos = 0; ASSERT(m_cpu != NULL); ret = pqos_cpu_check_core(m_cpu, lcore); if (ret != PQOS_RETVAL_OK) return PQOS_RETVAL_PARAM; ASSERT(m_cap != NULL); ret = pqos_l3ca_get_cos_num(m_cap, &num_l3_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) return ret; ret = pqos_l2ca_get_cos_num(m_cap, &num_l2_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) return ret; if (class_id >= num_l3_cos && class_id >= num_l2_cos) /* class_id is out of bounds */ return PQOS_RETVAL_PARAM; ret = cos_assoc_set(lcore, class_id); return ret; }
/** * @brief Gets highest COS id which could be used to configure set technologies * * @param [in] technology technologies bitmask to get highest common COS id for * @param [out] hi_class_id highest common COS id * * @return Operation status */ static int get_hi_cos_id(const unsigned technology, unsigned *hi_class_id) { 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); unsigned num_l2_cos = 0, num_l3_cos = 0, num_mba_cos = 0, num_cos = 0; int ret; if ((!l2_req && !l3_req && !mba_req) || hi_class_id == NULL) return PQOS_RETVAL_PARAM; ASSERT(m_cap != NULL); if (l3_req) { ret = pqos_l3ca_get_cos_num(m_cap, &num_l3_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) return ret; if (num_l3_cos == 0) return PQOS_RETVAL_ERROR; num_cos = num_l3_cos; } if (l2_req) { ret = pqos_l2ca_get_cos_num(m_cap, &num_l2_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) return ret; if (num_l2_cos == 0) return PQOS_RETVAL_ERROR; if (num_cos == 0 || num_l2_cos < num_cos) num_cos = num_l2_cos; } if (mba_req) { ret = pqos_mba_get_cos_num(m_cap, &num_mba_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) return ret; if (num_mba_cos == 0) return PQOS_RETVAL_ERROR; if (num_cos == 0 || num_mba_cos < num_cos) num_cos = num_mba_cos; } *hi_class_id = num_cos - 1; return PQOS_RETVAL_OK; }
int pqos_alloc_assoc_set(const unsigned lcore, const unsigned class_id) { int ret = PQOS_RETVAL_OK; unsigned num_l2_cos = 0, num_l3_cos = 0; const uint32_t reg = PQOS_MSR_ASSOC; uint64_t val = 0; _pqos_api_lock(); ret = _pqos_check_init(1); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return ret; } ASSERT(m_cpu != NULL); ret = pqos_cpu_check_core(m_cpu, lcore); if (ret != PQOS_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } ASSERT(m_cap != NULL); ret = pqos_l3ca_get_cos_num(m_cap, &num_l3_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) { _pqos_api_unlock(); return ret; } ret = pqos_l2ca_get_cos_num(m_cap, &num_l2_cos); if (ret != PQOS_RETVAL_OK && ret != PQOS_RETVAL_RESOURCE) { _pqos_api_unlock(); return ret; } if (class_id > num_l3_cos && class_id > num_l2_cos) { /* class_id is out of bounds */ _pqos_api_unlock(); return PQOS_RETVAL_PARAM; } ret = msr_read(lcore, reg, &val); if (ret != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } val &= (~PQOS_MSR_ASSOC_QECOS_MASK); val |= (((uint64_t) class_id) << PQOS_MSR_ASSOC_QECOS_SHIFT); ret = msr_write(lcore, reg, val); if (ret != MACHINE_RETVAL_OK) { _pqos_api_unlock(); return PQOS_RETVAL_ERROR; } _pqos_api_unlock(); return PQOS_RETVAL_OK; }
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; }