b2b2864150aaaf4827f10046eaa183cd9cab06c8
[linux-block.git] / arch / x86 / kernel / cpu / intel_rdt.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_INTEL_RDT_H
3 #define _ASM_X86_INTEL_RDT_H
4
5 #include <linux/sched.h>
6 #include <linux/kernfs.h>
7 #include <linux/jump_label.h>
8
9 #define IA32_L3_QOS_CFG         0xc81
10 #define IA32_L2_QOS_CFG         0xc82
11 #define IA32_L3_CBM_BASE        0xc90
12 #define IA32_L2_CBM_BASE        0xd10
13 #define IA32_MBA_THRTL_BASE     0xd50
14
15 #define L3_QOS_CDP_ENABLE       0x01ULL
16
17 #define L2_QOS_CDP_ENABLE       0x01ULL
18
19 /*
20  * Event IDs are used to program IA32_QM_EVTSEL before reading event
21  * counter from IA32_QM_CTR
22  */
23 #define QOS_L3_OCCUP_EVENT_ID           0x01
24 #define QOS_L3_MBM_TOTAL_EVENT_ID       0x02
25 #define QOS_L3_MBM_LOCAL_EVENT_ID       0x03
26
27 #define CQM_LIMBOCHECK_INTERVAL 1000
28
29 #define MBM_CNTR_WIDTH                  24
30 #define MBM_OVERFLOW_INTERVAL           1000
31 #define MAX_MBA_BW                      100u
32
33 #define RMID_VAL_ERROR                  BIT_ULL(63)
34 #define RMID_VAL_UNAVAIL                BIT_ULL(62)
35
36 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
37
38 /**
39  * struct mon_evt - Entry in the event list of a resource
40  * @evtid:              event id
41  * @name:               name of the event
42  */
43 struct mon_evt {
44         u32                     evtid;
45         char                    *name;
46         struct list_head        list;
47 };
48
49 /**
50  * struct mon_data_bits - Monitoring details for each event file
51  * @rid:               Resource id associated with the event file.
52  * @evtid:             Event id associated with the event file
53  * @domid:             The domain to which the event file belongs
54  */
55 union mon_data_bits {
56         void *priv;
57         struct {
58                 unsigned int rid        : 10;
59                 unsigned int evtid      : 8;
60                 unsigned int domid      : 14;
61         } u;
62 };
63
64 struct rmid_read {
65         struct rdtgroup         *rgrp;
66         struct rdt_domain       *d;
67         int                     evtid;
68         bool                    first;
69         u64                     val;
70 };
71
72 extern unsigned int intel_cqm_threshold;
73 extern bool rdt_alloc_capable;
74 extern bool rdt_mon_capable;
75 extern unsigned int rdt_mon_features;
76
77 enum rdt_group_type {
78         RDTCTRL_GROUP = 0,
79         RDTMON_GROUP,
80         RDT_NUM_GROUP,
81 };
82
83 /**
84  * enum rdtgrp_mode - Mode of a RDT resource group
85  * @RDT_MODE_SHAREABLE: This resource group allows sharing of its allocations
86  * @RDT_MODE_EXCLUSIVE: No sharing of this resource group's allocations allowed
87  *
88  * The mode of a resource group enables control over the allowed overlap
89  * between allocations associated with different resource groups (classes
90  * of service). User is able to modify the mode of a resource group by
91  * writing to the "mode" resctrl file associated with the resource group.
92  */
93 enum rdtgrp_mode {
94         RDT_MODE_SHAREABLE = 0,
95         RDT_MODE_EXCLUSIVE,
96
97         /* Must be last */
98         RDT_NUM_MODES,
99 };
100
101 /**
102  * struct mongroup - store mon group's data in resctrl fs.
103  * @mon_data_kn         kernlfs node for the mon_data directory
104  * @parent:                     parent rdtgrp
105  * @crdtgrp_list:               child rdtgroup node list
106  * @rmid:                       rmid for this rdtgroup
107  */
108 struct mongroup {
109         struct kernfs_node      *mon_data_kn;
110         struct rdtgroup         *parent;
111         struct list_head        crdtgrp_list;
112         u32                     rmid;
113 };
114
115 /**
116  * struct rdtgroup - store rdtgroup's data in resctrl file system.
117  * @kn:                         kernfs node
118  * @rdtgroup_list:              linked list for all rdtgroups
119  * @closid:                     closid for this rdtgroup
120  * @cpu_mask:                   CPUs assigned to this rdtgroup
121  * @flags:                      status bits
122  * @waitcount:                  how many cpus expect to find this
123  *                              group when they acquire rdtgroup_mutex
124  * @type:                       indicates type of this rdtgroup - either
125  *                              monitor only or ctrl_mon group
126  * @mon:                        mongroup related data
127  * @mode:                       mode of resource group
128  */
129 struct rdtgroup {
130         struct kernfs_node      *kn;
131         struct list_head        rdtgroup_list;
132         u32                     closid;
133         struct cpumask          cpu_mask;
134         int                     flags;
135         atomic_t                waitcount;
136         enum rdt_group_type     type;
137         struct mongroup         mon;
138         enum rdtgrp_mode        mode;
139 };
140
141 /* rdtgroup.flags */
142 #define RDT_DELETED             1
143
144 /* rftype.flags */
145 #define RFTYPE_FLAGS_CPUS_LIST  1
146
147 /*
148  * Define the file type flags for base and info directories.
149  */
150 #define RFTYPE_INFO                     BIT(0)
151 #define RFTYPE_BASE                     BIT(1)
152 #define RF_CTRLSHIFT                    4
153 #define RF_MONSHIFT                     5
154 #define RF_TOPSHIFT                     6
155 #define RFTYPE_CTRL                     BIT(RF_CTRLSHIFT)
156 #define RFTYPE_MON                      BIT(RF_MONSHIFT)
157 #define RFTYPE_TOP                      BIT(RF_TOPSHIFT)
158 #define RFTYPE_RES_CACHE                BIT(8)
159 #define RFTYPE_RES_MB                   BIT(9)
160 #define RF_CTRL_INFO                    (RFTYPE_INFO | RFTYPE_CTRL)
161 #define RF_MON_INFO                     (RFTYPE_INFO | RFTYPE_MON)
162 #define RF_TOP_INFO                     (RFTYPE_INFO | RFTYPE_TOP)
163 #define RF_CTRL_BASE                    (RFTYPE_BASE | RFTYPE_CTRL)
164
165 /* List of all resource groups */
166 extern struct list_head rdt_all_groups;
167
168 extern int max_name_width, max_data_width;
169
170 int __init rdtgroup_init(void);
171
172 /**
173  * struct rftype - describe each file in the resctrl file system
174  * @name:       File name
175  * @mode:       Access mode
176  * @kf_ops:     File operations
177  * @flags:      File specific RFTYPE_FLAGS_* flags
178  * @fflags:     File specific RF_* or RFTYPE_* flags
179  * @seq_show:   Show content of the file
180  * @write:      Write to the file
181  */
182 struct rftype {
183         char                    *name;
184         umode_t                 mode;
185         struct kernfs_ops       *kf_ops;
186         unsigned long           flags;
187         unsigned long           fflags;
188
189         int (*seq_show)(struct kernfs_open_file *of,
190                         struct seq_file *sf, void *v);
191         /*
192          * write() is the generic write callback which maps directly to
193          * kernfs write operation and overrides all other operations.
194          * Maximum write size is determined by ->max_write_len.
195          */
196         ssize_t (*write)(struct kernfs_open_file *of,
197                          char *buf, size_t nbytes, loff_t off);
198 };
199
200 /**
201  * struct mbm_state - status for each MBM counter in each domain
202  * @chunks:     Total data moved (multiply by rdt_group.mon_scale to get bytes)
203  * @prev_msr    Value of IA32_QM_CTR for this RMID last time we read it
204  * @chunks_bw   Total local data moved. Used for bandwidth calculation
205  * @prev_bw_msr:Value of previous IA32_QM_CTR for bandwidth counting
206  * @prev_bw     The most recent bandwidth in MBps
207  * @delta_bw    Difference between the current and previous bandwidth
208  * @delta_comp  Indicates whether to compute the delta_bw
209  */
210 struct mbm_state {
211         u64     chunks;
212         u64     prev_msr;
213         u64     chunks_bw;
214         u64     prev_bw_msr;
215         u32     prev_bw;
216         u32     delta_bw;
217         bool    delta_comp;
218 };
219
220 /**
221  * struct rdt_domain - group of cpus sharing an RDT resource
222  * @list:       all instances of this resource
223  * @id:         unique id for this instance
224  * @cpu_mask:   which cpus share this resource
225  * @rmid_busy_llc:
226  *              bitmap of which limbo RMIDs are above threshold
227  * @mbm_total:  saved state for MBM total bandwidth
228  * @mbm_local:  saved state for MBM local bandwidth
229  * @mbm_over:   worker to periodically read MBM h/w counters
230  * @cqm_limbo:  worker to periodically read CQM h/w counters
231  * @mbm_work_cpu:
232  *              worker cpu for MBM h/w counters
233  * @cqm_work_cpu:
234  *              worker cpu for CQM h/w counters
235  * @ctrl_val:   array of cache or mem ctrl values (indexed by CLOSID)
236  * @mbps_val:   When mba_sc is enabled, this holds the bandwidth in MBps
237  * @new_ctrl:   new ctrl value to be loaded
238  * @have_new_ctrl: did user provide new_ctrl for this domain
239  */
240 struct rdt_domain {
241         struct list_head        list;
242         int                     id;
243         struct cpumask          cpu_mask;
244         unsigned long           *rmid_busy_llc;
245         struct mbm_state        *mbm_total;
246         struct mbm_state        *mbm_local;
247         struct delayed_work     mbm_over;
248         struct delayed_work     cqm_limbo;
249         int                     mbm_work_cpu;
250         int                     cqm_work_cpu;
251         u32                     *ctrl_val;
252         u32                     *mbps_val;
253         u32                     new_ctrl;
254         bool                    have_new_ctrl;
255 };
256
257 /**
258  * struct msr_param - set a range of MSRs from a domain
259  * @res:       The resource to use
260  * @low:       Beginning index from base MSR
261  * @high:      End index
262  */
263 struct msr_param {
264         struct rdt_resource     *res;
265         int                     low;
266         int                     high;
267 };
268
269 /**
270  * struct rdt_cache - Cache allocation related data
271  * @cbm_len:            Length of the cache bit mask
272  * @min_cbm_bits:       Minimum number of consecutive bits to be set
273  * @cbm_idx_mult:       Multiplier of CBM index
274  * @cbm_idx_offset:     Offset of CBM index. CBM index is computed by:
275  *                      closid * cbm_idx_multi + cbm_idx_offset
276  *                      in a cache bit mask
277  * @shareable_bits:     Bitmask of shareable resource with other
278  *                      executing entities
279  */
280 struct rdt_cache {
281         unsigned int    cbm_len;
282         unsigned int    min_cbm_bits;
283         unsigned int    cbm_idx_mult;
284         unsigned int    cbm_idx_offset;
285         unsigned int    shareable_bits;
286 };
287
288 /**
289  * struct rdt_membw - Memory bandwidth allocation related data
290  * @max_delay:          Max throttle delay. Delay is the hardware
291  *                      representation for memory bandwidth.
292  * @min_bw:             Minimum memory bandwidth percentage user can request
293  * @bw_gran:            Granularity at which the memory bandwidth is allocated
294  * @delay_linear:       True if memory B/W delay is in linear scale
295  * @mba_sc:             True if MBA software controller(mba_sc) is enabled
296  * @mb_map:             Mapping of memory B/W percentage to memory B/W delay
297  */
298 struct rdt_membw {
299         u32             max_delay;
300         u32             min_bw;
301         u32             bw_gran;
302         u32             delay_linear;
303         bool            mba_sc;
304         u32             *mb_map;
305 };
306
307 static inline bool is_llc_occupancy_enabled(void)
308 {
309         return (rdt_mon_features & (1 << QOS_L3_OCCUP_EVENT_ID));
310 }
311
312 static inline bool is_mbm_total_enabled(void)
313 {
314         return (rdt_mon_features & (1 << QOS_L3_MBM_TOTAL_EVENT_ID));
315 }
316
317 static inline bool is_mbm_local_enabled(void)
318 {
319         return (rdt_mon_features & (1 << QOS_L3_MBM_LOCAL_EVENT_ID));
320 }
321
322 static inline bool is_mbm_enabled(void)
323 {
324         return (is_mbm_total_enabled() || is_mbm_local_enabled());
325 }
326
327 static inline bool is_mbm_event(int e)
328 {
329         return (e >= QOS_L3_MBM_TOTAL_EVENT_ID &&
330                 e <= QOS_L3_MBM_LOCAL_EVENT_ID);
331 }
332
333 /**
334  * struct rdt_resource - attributes of an RDT resource
335  * @rid:                The index of the resource
336  * @alloc_enabled:      Is allocation enabled on this machine
337  * @mon_enabled:                Is monitoring enabled for this feature
338  * @alloc_capable:      Is allocation available on this machine
339  * @mon_capable:                Is monitor feature available on this machine
340  * @name:               Name to use in "schemata" file
341  * @num_closid:         Number of CLOSIDs available
342  * @cache_level:        Which cache level defines scope of this resource
343  * @default_ctrl:       Specifies default cache cbm or memory B/W percent.
344  * @msr_base:           Base MSR address for CBMs
345  * @msr_update:         Function pointer to update QOS MSRs
346  * @data_width:         Character width of data when displaying
347  * @domains:            All domains for this resource
348  * @cache:              Cache allocation related data
349  * @format_str:         Per resource format string to show domain value
350  * @parse_ctrlval:      Per resource function pointer to parse control values
351  * @evt_list:                   List of monitoring events
352  * @num_rmid:                   Number of RMIDs available
353  * @mon_scale:                  cqm counter * mon_scale = occupancy in bytes
354  * @fflags:                     flags to choose base and info files
355  */
356 struct rdt_resource {
357         int                     rid;
358         bool                    alloc_enabled;
359         bool                    mon_enabled;
360         bool                    alloc_capable;
361         bool                    mon_capable;
362         char                    *name;
363         int                     num_closid;
364         int                     cache_level;
365         u32                     default_ctrl;
366         unsigned int            msr_base;
367         void (*msr_update)      (struct rdt_domain *d, struct msr_param *m,
368                                  struct rdt_resource *r);
369         int                     data_width;
370         struct list_head        domains;
371         struct rdt_cache        cache;
372         struct rdt_membw        membw;
373         const char              *format_str;
374         int (*parse_ctrlval)    (void *data, struct rdt_resource *r,
375                                  struct rdt_domain *d);
376         struct list_head        evt_list;
377         int                     num_rmid;
378         unsigned int            mon_scale;
379         unsigned long           fflags;
380 };
381
382 int parse_cbm(void *_data, struct rdt_resource *r, struct rdt_domain *d);
383 int parse_bw(void *_buf, struct rdt_resource *r,  struct rdt_domain *d);
384
385 extern struct mutex rdtgroup_mutex;
386
387 extern struct rdt_resource rdt_resources_all[];
388 extern struct rdtgroup rdtgroup_default;
389 DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
390
391 int __init rdtgroup_init(void);
392
393 enum {
394         RDT_RESOURCE_L3,
395         RDT_RESOURCE_L3DATA,
396         RDT_RESOURCE_L3CODE,
397         RDT_RESOURCE_L2,
398         RDT_RESOURCE_L2DATA,
399         RDT_RESOURCE_L2CODE,
400         RDT_RESOURCE_MBA,
401
402         /* Must be the last */
403         RDT_NUM_RESOURCES,
404 };
405
406 #define for_each_capable_rdt_resource(r)                                      \
407         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
408              r++)                                                             \
409                 if (r->alloc_capable || r->mon_capable)
410
411 #define for_each_alloc_capable_rdt_resource(r)                                \
412         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
413              r++)                                                             \
414                 if (r->alloc_capable)
415
416 #define for_each_mon_capable_rdt_resource(r)                                  \
417         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
418              r++)                                                             \
419                 if (r->mon_capable)
420
421 #define for_each_alloc_enabled_rdt_resource(r)                                \
422         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
423              r++)                                                             \
424                 if (r->alloc_enabled)
425
426 #define for_each_mon_enabled_rdt_resource(r)                                  \
427         for (r = rdt_resources_all; r < rdt_resources_all + RDT_NUM_RESOURCES;\
428              r++)                                                             \
429                 if (r->mon_enabled)
430
431 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
432 union cpuid_0x10_1_eax {
433         struct {
434                 unsigned int cbm_len:5;
435         } split;
436         unsigned int full;
437 };
438
439 /* CPUID.(EAX=10H, ECX=ResID=3).EAX */
440 union cpuid_0x10_3_eax {
441         struct {
442                 unsigned int max_delay:12;
443         } split;
444         unsigned int full;
445 };
446
447 /* CPUID.(EAX=10H, ECX=ResID).EDX */
448 union cpuid_0x10_x_edx {
449         struct {
450                 unsigned int cos_max:16;
451         } split;
452         unsigned int full;
453 };
454
455 void rdt_last_cmd_clear(void);
456 void rdt_last_cmd_puts(const char *s);
457 void rdt_last_cmd_printf(const char *fmt, ...);
458
459 void rdt_ctrl_update(void *arg);
460 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
461 void rdtgroup_kn_unlock(struct kernfs_node *kn);
462 struct rdt_domain *rdt_find_domain(struct rdt_resource *r, int id,
463                                    struct list_head **pos);
464 ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
465                                 char *buf, size_t nbytes, loff_t off);
466 int rdtgroup_schemata_show(struct kernfs_open_file *of,
467                            struct seq_file *s, void *v);
468 enum rdtgrp_mode rdtgroup_mode_by_closid(int closid);
469 struct rdt_domain *get_domain_from_cpu(int cpu, struct rdt_resource *r);
470 int update_domains(struct rdt_resource *r, int closid);
471 void closid_free(int closid);
472 int alloc_rmid(void);
473 void free_rmid(u32 rmid);
474 int rdt_get_mon_l3_config(struct rdt_resource *r);
475 void mon_event_count(void *info);
476 int rdtgroup_mondata_show(struct seq_file *m, void *arg);
477 void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
478                                     unsigned int dom_id);
479 void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
480                                     struct rdt_domain *d);
481 void mon_event_read(struct rmid_read *rr, struct rdt_domain *d,
482                     struct rdtgroup *rdtgrp, int evtid, int first);
483 void mbm_setup_overflow_handler(struct rdt_domain *dom,
484                                 unsigned long delay_ms);
485 void mbm_handle_overflow(struct work_struct *work);
486 bool is_mba_sc(struct rdt_resource *r);
487 void setup_default_ctrlval(struct rdt_resource *r, u32 *dc, u32 *dm);
488 u32 delay_bw_map(unsigned long bw, struct rdt_resource *r);
489 void cqm_setup_limbo_handler(struct rdt_domain *dom, unsigned long delay_ms);
490 void cqm_handle_limbo(struct work_struct *work);
491 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
492 void __check_limbo(struct rdt_domain *d, bool force_free);
493
494 /*
495  * Define the hooks for Cache Pseudo-Locking to use within rdt_mount().
496  * These are no-ops provided for the new kernfs changes to use as a
497  * baseline in preparation for a conflict-free merge between it
498  * (kernfs changes) and the Cache Pseudo-Locking enabling.
499  */
500 static inline int rdt_pseudo_lock_init(void) { return 0; }
501 static inline void rdt_pseudo_lock_release(void) { }
502
503 #endif /* _ASM_X86_INTEL_RDT_H */