Merge branch 'x86-cache-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / x86 / include / asm / intel_rdt.h
1 #ifndef _ASM_X86_INTEL_RDT_H
2 #define _ASM_X86_INTEL_RDT_H
3
4 #ifdef CONFIG_INTEL_RDT_A
5
6 #include <linux/kernfs.h>
7 #include <linux/jump_label.h>
8
9 #include <asm/intel_rdt_common.h>
10
11 #define IA32_L3_QOS_CFG         0xc81
12 #define IA32_L3_CBM_BASE        0xc90
13 #define IA32_L2_CBM_BASE        0xd10
14
15 #define L3_QOS_CDP_ENABLE       0x01ULL
16
17 /**
18  * struct rdtgroup - store rdtgroup's data in resctrl file system.
19  * @kn:                         kernfs node
20  * @rdtgroup_list:              linked list for all rdtgroups
21  * @closid:                     closid for this rdtgroup
22  * @cpu_mask:                   CPUs assigned to this rdtgroup
23  * @flags:                      status bits
24  * @waitcount:                  how many cpus expect to find this
25  *                              group when they acquire rdtgroup_mutex
26  */
27 struct rdtgroup {
28         struct kernfs_node      *kn;
29         struct list_head        rdtgroup_list;
30         int                     closid;
31         struct cpumask          cpu_mask;
32         int                     flags;
33         atomic_t                waitcount;
34 };
35
36 /* rdtgroup.flags */
37 #define RDT_DELETED             1
38
39 /* List of all resource groups */
40 extern struct list_head rdt_all_groups;
41
42 int __init rdtgroup_init(void);
43
44 /**
45  * struct rftype - describe each file in the resctrl file system
46  * @name: file name
47  * @mode: access mode
48  * @kf_ops: operations
49  * @seq_show: show content of the file
50  * @write: write to the file
51  */
52 struct rftype {
53         char                    *name;
54         umode_t                 mode;
55         struct kernfs_ops       *kf_ops;
56
57         int (*seq_show)(struct kernfs_open_file *of,
58                         struct seq_file *sf, void *v);
59         /*
60          * write() is the generic write callback which maps directly to
61          * kernfs write operation and overrides all other operations.
62          * Maximum write size is determined by ->max_write_len.
63          */
64         ssize_t (*write)(struct kernfs_open_file *of,
65                          char *buf, size_t nbytes, loff_t off);
66 };
67
68 /**
69  * struct rdt_resource - attributes of an RDT resource
70  * @enabled:                    Is this feature enabled on this machine
71  * @capable:                    Is this feature available on this machine
72  * @name:                       Name to use in "schemata" file
73  * @num_closid:                 Number of CLOSIDs available
74  * @max_cbm:                    Largest Cache Bit Mask allowed
75  * @min_cbm_bits:               Minimum number of consecutive bits to be set
76  *                              in a cache bit mask
77  * @domains:                    All domains for this resource
78  * @num_domains:                Number of domains active
79  * @msr_base:                   Base MSR address for CBMs
80  * @tmp_cbms:                   Scratch space when updating schemata
81  * @num_tmp_cbms:               Number of CBMs in tmp_cbms
82  * @cache_level:                Which cache level defines scope of this domain
83  * @cbm_idx_multi:              Multiplier of CBM index
84  * @cbm_idx_offset:             Offset of CBM index. CBM index is computed by:
85  *                              closid * cbm_idx_multi + cbm_idx_offset
86  */
87 struct rdt_resource {
88         bool                    enabled;
89         bool                    capable;
90         char                    *name;
91         int                     num_closid;
92         int                     cbm_len;
93         int                     min_cbm_bits;
94         u32                     max_cbm;
95         struct list_head        domains;
96         int                     num_domains;
97         int                     msr_base;
98         u32                     *tmp_cbms;
99         int                     num_tmp_cbms;
100         int                     cache_level;
101         int                     cbm_idx_multi;
102         int                     cbm_idx_offset;
103 };
104
105 /**
106  * struct rdt_domain - group of cpus sharing an RDT resource
107  * @list:       all instances of this resource
108  * @id:         unique id for this instance
109  * @cpu_mask:   which cpus share this resource
110  * @cbm:        array of cache bit masks (indexed by CLOSID)
111  */
112 struct rdt_domain {
113         struct list_head        list;
114         int                     id;
115         struct cpumask          cpu_mask;
116         u32                     *cbm;
117 };
118
119 /**
120  * struct msr_param - set a range of MSRs from a domain
121  * @res:       The resource to use
122  * @low:       Beginning index from base MSR
123  * @high:      End index
124  */
125 struct msr_param {
126         struct rdt_resource     *res;
127         int                     low;
128         int                     high;
129 };
130
131 extern struct mutex rdtgroup_mutex;
132
133 extern struct rdt_resource rdt_resources_all[];
134 extern struct rdtgroup rdtgroup_default;
135 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
136
137 int __init rdtgroup_init(void);
138
139 enum {
140         RDT_RESOURCE_L3,
141         RDT_RESOURCE_L3DATA,
142         RDT_RESOURCE_L3CODE,
143         RDT_RESOURCE_L2,
144
145         /* Must be the last */
146         RDT_NUM_RESOURCES,
147 };
148
149 #define for_each_capable_rdt_resource(r)                                      \
150         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
151              r++)                                                             \
152                 if (r->capable)
153
154 #define for_each_enabled_rdt_resource(r)                                      \
155         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
156              r++)                                                             \
157                 if (r->enabled)
158
159 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
160 union cpuid_0x10_1_eax {
161         struct {
162                 unsigned int cbm_len:5;
163         } split;
164         unsigned int full;
165 };
166
167 /* CPUID.(EAX=10H, ECX=ResID=1).EDX */
168 union cpuid_0x10_1_edx {
169         struct {
170                 unsigned int cos_max:16;
171         } split;
172         unsigned int full;
173 };
174
175 DECLARE_PER_CPU_READ_MOSTLY(int, cpu_closid);
176
177 void rdt_cbm_update(void *arg);
178 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
179 void rdtgroup_kn_unlock(struct kernfs_node *kn);
180 ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
181                                 char *buf, size_t nbytes, loff_t off);
182 int rdtgroup_schemata_show(struct kernfs_open_file *of,
183                            struct seq_file *s, void *v);
184
185 /*
186  * intel_rdt_sched_in() - Writes the task's CLOSid to IA32_PQR_MSR
187  *
188  * Following considerations are made so that this has minimal impact
189  * on scheduler hot path:
190  * - This will stay as no-op unless we are running on an Intel SKU
191  *   which supports resource control and we enable by mounting the
192  *   resctrl file system.
193  * - Caches the per cpu CLOSid values and does the MSR write only
194  *   when a task with a different CLOSid is scheduled in.
195  *
196  * Must be called with preemption disabled.
197  */
198 static inline void intel_rdt_sched_in(void)
199 {
200         if (static_branch_likely(&rdt_enable_key)) {
201                 struct intel_pqr_state *state = this_cpu_ptr(&pqr_state);
202                 int closid;
203
204                 /*
205                  * If this task has a closid assigned, use it.
206                  * Else use the closid assigned to this cpu.
207                  */
208                 closid = current->closid;
209                 if (closid == 0)
210                         closid = this_cpu_read(cpu_closid);
211
212                 if (closid != state->closid) {
213                         state->closid = closid;
214                         wrmsr(MSR_IA32_PQR_ASSOC, state->rmid, closid);
215                 }
216         }
217 }
218
219 #else
220
221 static inline void intel_rdt_sched_in(void) {}
222
223 #endif /* CONFIG_INTEL_RDT_A */
224 #endif /* _ASM_X86_INTEL_RDT_H */