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; }
int hw_l2ca_set(const unsigned l2id, const unsigned num_ca, const struct pqos_l2ca *ca) { int ret = PQOS_RETVAL_OK; unsigned i = 0, count = 0, core = 0; if (ca == NULL || num_ca == 0) 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) 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); 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); return PQOS_RETVAL_PARAM; } } /** * Pick one core from the L2 cluster and * perform MSR writes to COS registers on the cluster. */ ASSERT(m_cpu != NULL); ret = pqos_cpu_get_one_by_l2id(m_cpu, l2id, &core); if (ret != PQOS_RETVAL_OK) 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) return PQOS_RETVAL_ERROR; } 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 hw_l2ca_get(const unsigned l2id, 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; if (num_ca == NULL || ca == NULL || max_num_ca == 0) return PQOS_RETVAL_PARAM; ASSERT(m_cap != NULL); ret = pqos_l2ca_get_cos_num(m_cap, &count); if (ret != PQOS_RETVAL_OK) return PQOS_RETVAL_RESOURCE; /* L2 CAT not supported */ if (max_num_ca < count) /* Not enough space to store the classes */ return PQOS_RETVAL_PARAM; ASSERT(m_cpu != NULL); ret = pqos_cpu_get_one_by_l2id(m_cpu, l2id, &core); if (ret != PQOS_RETVAL_OK) return ret; for (i = 0; i < count; i++) { const 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) return PQOS_RETVAL_ERROR; ca[i].class_id = i; ca[i].ways_mask = val; } *num_ca = count; return ret; }
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_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; }