#define _GNU_SOURCE #include "internal.h" #include #include #include clos_entry_t clos_table[MAX_CLOS]; static uint32_t default_mask; static bool initialized; int clos_init(icepick_topology_t *topo) { if (initialized) return 0; memset(clos_table, 0, sizeof(clos_table)); default_mask = topo->default_way_mask; clos_table[0].allocated = true; clos_table[0].way_mask = default_mask; initialized = true; return 0; } int clos_allocate(unsigned clos_id, uint32_t way_mask) { if (clos_id == 0 || clos_id >= MAX_CLOS) return ICEPICK_E_INVALID; if (clos_table[clos_id].allocated) return ICEPICK_E_NO_CLOS; clos_table[clos_id].allocated = true; clos_table[clos_id].way_mask = way_mask; clos_table[0].way_mask &= ~way_mask; return 0; } int clos_release(unsigned clos_id) { if (clos_id == 0 || clos_id >= MAX_CLOS) return ICEPICK_E_INVALID; if (!clos_table[clos_id].allocated) return 0; clos_table[0].way_mask |= clos_table[clos_id].way_mask; clos_table[clos_id].allocated = false; clos_table[clos_id].way_mask = 0; return 0; } int clos_configure_mask(int msr_fd, unsigned clos_id, uint32_t way_mask) { if (clos_id >= MAX_CLOS) return ICEPICK_E_INVALID; uint32_t msr = MSR_IA32_L3_QOS_MASK_0 + clos_id; return msr_write(msr_fd, msr, way_mask); } int clos_associate_thread(int msr_fd, unsigned clos_id) { if (clos_id >= MAX_CLOS) return ICEPICK_E_INVALID; uint64_t value; int ret = msr_read(msr_fd, MSR_IA32_PQR_ASSOC, &value); if (ret < 0) return ret; value = (value & 0xFFFFFFFF) | ((uint64_t)clos_id << 32); return msr_write(msr_fd, MSR_IA32_PQR_ASSOC, value); } uint32_t clos_get_default_mask(void) { return default_mask; }