cache line locking on AMD x86_64 utilising L3 CAT pseudo-locking
1#define _GNU_SOURCE
2#include "internal.h"
3#include <sched.h>
4#include <string.h>
5#include <unistd.h>
6
7clos_entry_t clos_table[MAX_CLOS];
8static uint32_t default_mask;
9static bool initialized;
10
11int clos_init(icepick_topology_t *topo)
12{
13 if (initialized)
14 return 0;
15
16 memset(clos_table, 0, sizeof(clos_table));
17
18 default_mask = topo->default_way_mask;
19
20 clos_table[0].allocated = true;
21 clos_table[0].way_mask = default_mask;
22
23 initialized = true;
24 return 0;
25}
26
27int clos_allocate(unsigned clos_id, uint32_t way_mask)
28{
29 if (clos_id == 0 || clos_id >= MAX_CLOS)
30 return ICEPICK_E_INVALID;
31
32 if (clos_table[clos_id].allocated)
33 return ICEPICK_E_NO_CLOS;
34
35 clos_table[clos_id].allocated = true;
36 clos_table[clos_id].way_mask = way_mask;
37
38 clos_table[0].way_mask &= ~way_mask;
39
40 return 0;
41}
42
43int clos_release(unsigned clos_id)
44{
45 if (clos_id == 0 || clos_id >= MAX_CLOS)
46 return ICEPICK_E_INVALID;
47
48 if (!clos_table[clos_id].allocated)
49 return 0;
50
51 clos_table[0].way_mask |= clos_table[clos_id].way_mask;
52
53 clos_table[clos_id].allocated = false;
54 clos_table[clos_id].way_mask = 0;
55
56 return 0;
57}
58
59int clos_configure_mask(int msr_fd, unsigned clos_id, uint32_t way_mask)
60{
61 if (clos_id >= MAX_CLOS)
62 return ICEPICK_E_INVALID;
63
64 uint32_t msr = MSR_IA32_L3_QOS_MASK_0 + clos_id;
65 return msr_write(msr_fd, msr, way_mask);
66}
67
68int clos_associate_thread(int msr_fd, unsigned clos_id)
69{
70 if (clos_id >= MAX_CLOS)
71 return ICEPICK_E_INVALID;
72
73 uint64_t value;
74 int ret = msr_read(msr_fd, MSR_IA32_PQR_ASSOC, &value);
75 if (ret < 0)
76 return ret;
77
78 value = (value & 0xFFFFFFFF) | ((uint64_t)clos_id << 32);
79 return msr_write(msr_fd, MSR_IA32_PQR_ASSOC, value);
80}
81
82uint32_t clos_get_default_mask(void)
83{
84 return default_mask;
85}
86
87int mba_configure(int msr_fd, unsigned clos_id, unsigned throttle)
88{
89 if (clos_id >= MAX_CLOS)
90 return ICEPICK_E_INVALID;
91
92 if (throttle == 0)
93 return 0;
94
95 uint32_t msr = MSR_IA32_MBA_THRTL_BASE + clos_id;
96 return msr_write(msr_fd, msr, throttle);
97}