1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _FS_RESCTRL_INTERNAL_H
3 #define _FS_RESCTRL_INTERNAL_H
4
5 #include <linux/resctrl.h>
6 #include <linux/kernfs.h>
7 #include <linux/fs_context.h>
8 #include <linux/tick.h>
9
10 #define CQM_LIMBOCHECK_INTERVAL 1000
11
12 /**
13 * cpumask_any_housekeeping() - Choose any CPU in @mask, preferring those that
14 * aren't marked nohz_full
15 * @mask: The mask to pick a CPU from.
16 * @exclude_cpu:The CPU to avoid picking.
17 *
18 * Returns a CPU from @mask, but not @exclude_cpu. If there are housekeeping
19 * CPUs that don't use nohz_full, these are preferred. Pass
20 * RESCTRL_PICK_ANY_CPU to avoid excluding any CPUs.
21 *
22 * When a CPU is excluded, returns >= nr_cpu_ids if no CPUs are available.
23 */
24 static inline unsigned int
cpumask_any_housekeeping(const struct cpumask * mask,int exclude_cpu)25 cpumask_any_housekeeping(const struct cpumask *mask, int exclude_cpu)
26 {
27 unsigned int cpu;
28
29 /* Try to find a CPU that isn't nohz_full to use in preference */
30 if (tick_nohz_full_enabled()) {
31 cpu = cpumask_any_andnot_but(mask, tick_nohz_full_mask, exclude_cpu);
32 if (cpu < nr_cpu_ids)
33 return cpu;
34 }
35
36 return cpumask_any_but(mask, exclude_cpu);
37 }
38
39 struct rdt_fs_context {
40 struct kernfs_fs_context kfc;
41 bool enable_cdpl2;
42 bool enable_cdpl3;
43 bool enable_mba_mbps;
44 bool enable_debug;
45 };
46
rdt_fc2context(struct fs_context * fc)47 static inline struct rdt_fs_context *rdt_fc2context(struct fs_context *fc)
48 {
49 struct kernfs_fs_context *kfc = fc->fs_private;
50
51 return container_of(kfc, struct rdt_fs_context, kfc);
52 }
53
54 /**
55 * struct mon_evt - Entry in the event list of a resource
56 * @evtid: event id
57 * @name: name of the event
58 * @configurable: true if the event is configurable
59 * @list: entry in &rdt_resource->evt_list
60 */
61 struct mon_evt {
62 enum resctrl_event_id evtid;
63 char *name;
64 bool configurable;
65 struct list_head list;
66 };
67
68 /**
69 * struct mon_data - Monitoring details for each event file.
70 * @list: Member of the global @mon_data_kn_priv_list list.
71 * @rid: Resource id associated with the event file.
72 * @evtid: Event id associated with the event file.
73 * @sum: Set when event must be summed across multiple
74 * domains.
75 * @domid: When @sum is zero this is the domain to which
76 * the event file belongs. When @sum is one this
77 * is the id of the L3 cache that all domains to be
78 * summed share.
79 *
80 * Pointed to by the kernfs kn->priv field of monitoring event files.
81 * Readers and writers must hold rdtgroup_mutex.
82 */
83 struct mon_data {
84 struct list_head list;
85 enum resctrl_res_level rid;
86 enum resctrl_event_id evtid;
87 int domid;
88 bool sum;
89 };
90
91 /**
92 * struct rmid_read - Data passed across smp_call*() to read event count.
93 * @rgrp: Resource group for which the counter is being read. If it is a parent
94 * resource group then its event count is summed with the count from all
95 * its child resource groups.
96 * @r: Resource describing the properties of the event being read.
97 * @d: Domain that the counter should be read from. If NULL then sum all
98 * domains in @r sharing L3 @ci.id
99 * @evtid: Which monitor event to read.
100 * @first: Initialize MBM counter when true.
101 * @ci_id: Cacheinfo id for L3. Only set when @d is NULL. Used when summing domains.
102 * @err: Error encountered when reading counter.
103 * @val: Returned value of event counter. If @rgrp is a parent resource group,
104 * @val includes the sum of event counts from its child resource groups.
105 * If @d is NULL, @val includes the sum of all domains in @r sharing @ci.id,
106 * (summed across child resource groups if @rgrp is a parent resource group).
107 * @arch_mon_ctx: Hardware monitor allocated for this read request (MPAM only).
108 */
109 struct rmid_read {
110 struct rdtgroup *rgrp;
111 struct rdt_resource *r;
112 struct rdt_mon_domain *d;
113 enum resctrl_event_id evtid;
114 bool first;
115 unsigned int ci_id;
116 int err;
117 u64 val;
118 void *arch_mon_ctx;
119 };
120
121 extern struct list_head resctrl_schema_all;
122
123 extern bool resctrl_mounted;
124
125 enum rdt_group_type {
126 RDTCTRL_GROUP = 0,
127 RDTMON_GROUP,
128 RDT_NUM_GROUP,
129 };
130
131 /**
132 * enum rdtgrp_mode - Mode of a RDT resource group
133 * @RDT_MODE_SHAREABLE: This resource group allows sharing of its allocations
134 * @RDT_MODE_EXCLUSIVE: No sharing of this resource group's allocations allowed
135 * @RDT_MODE_PSEUDO_LOCKSETUP: Resource group will be used for Pseudo-Locking
136 * @RDT_MODE_PSEUDO_LOCKED: No sharing of this resource group's allocations
137 * allowed AND the allocations are Cache Pseudo-Locked
138 * @RDT_NUM_MODES: Total number of modes
139 *
140 * The mode of a resource group enables control over the allowed overlap
141 * between allocations associated with different resource groups (classes
142 * of service). User is able to modify the mode of a resource group by
143 * writing to the "mode" resctrl file associated with the resource group.
144 *
145 * The "shareable", "exclusive", and "pseudo-locksetup" modes are set by
146 * writing the appropriate text to the "mode" file. A resource group enters
147 * "pseudo-locked" mode after the schemata is written while the resource
148 * group is in "pseudo-locksetup" mode.
149 */
150 enum rdtgrp_mode {
151 RDT_MODE_SHAREABLE = 0,
152 RDT_MODE_EXCLUSIVE,
153 RDT_MODE_PSEUDO_LOCKSETUP,
154 RDT_MODE_PSEUDO_LOCKED,
155
156 /* Must be last */
157 RDT_NUM_MODES,
158 };
159
160 /**
161 * struct mongroup - store mon group's data in resctrl fs.
162 * @mon_data_kn: kernfs node for the mon_data directory
163 * @parent: parent rdtgrp
164 * @crdtgrp_list: child rdtgroup node list
165 * @rmid: rmid for this rdtgroup
166 */
167 struct mongroup {
168 struct kernfs_node *mon_data_kn;
169 struct rdtgroup *parent;
170 struct list_head crdtgrp_list;
171 u32 rmid;
172 };
173
174 /**
175 * struct rdtgroup - store rdtgroup's data in resctrl file system.
176 * @kn: kernfs node
177 * @rdtgroup_list: linked list for all rdtgroups
178 * @closid: closid for this rdtgroup
179 * @cpu_mask: CPUs assigned to this rdtgroup
180 * @flags: status bits
181 * @waitcount: how many cpus expect to find this
182 * group when they acquire rdtgroup_mutex
183 * @type: indicates type of this rdtgroup - either
184 * monitor only or ctrl_mon group
185 * @mon: mongroup related data
186 * @mode: mode of resource group
187 * @mba_mbps_event: input monitoring event id when mba_sc is enabled
188 * @plr: pseudo-locked region
189 */
190 struct rdtgroup {
191 struct kernfs_node *kn;
192 struct list_head rdtgroup_list;
193 u32 closid;
194 struct cpumask cpu_mask;
195 int flags;
196 atomic_t waitcount;
197 enum rdt_group_type type;
198 struct mongroup mon;
199 enum rdtgrp_mode mode;
200 enum resctrl_event_id mba_mbps_event;
201 struct pseudo_lock_region *plr;
202 };
203
204 /* rdtgroup.flags */
205 #define RDT_DELETED 1
206
207 /* rftype.flags */
208 #define RFTYPE_FLAGS_CPUS_LIST 1
209
210 /*
211 * Define the file type flags for base and info directories.
212 */
213 #define RFTYPE_INFO BIT(0)
214
215 #define RFTYPE_BASE BIT(1)
216
217 #define RFTYPE_CTRL BIT(4)
218
219 #define RFTYPE_MON BIT(5)
220
221 #define RFTYPE_TOP BIT(6)
222
223 #define RFTYPE_RES_CACHE BIT(8)
224
225 #define RFTYPE_RES_MB BIT(9)
226
227 #define RFTYPE_DEBUG BIT(10)
228
229 #define RFTYPE_CTRL_INFO (RFTYPE_INFO | RFTYPE_CTRL)
230
231 #define RFTYPE_MON_INFO (RFTYPE_INFO | RFTYPE_MON)
232
233 #define RFTYPE_TOP_INFO (RFTYPE_INFO | RFTYPE_TOP)
234
235 #define RFTYPE_CTRL_BASE (RFTYPE_BASE | RFTYPE_CTRL)
236
237 #define RFTYPE_MON_BASE (RFTYPE_BASE | RFTYPE_MON)
238
239 /* List of all resource groups */
240 extern struct list_head rdt_all_groups;
241
242 extern int max_name_width;
243
244 /**
245 * struct rftype - describe each file in the resctrl file system
246 * @name: File name
247 * @mode: Access mode
248 * @kf_ops: File operations
249 * @flags: File specific RFTYPE_FLAGS_* flags
250 * @fflags: File specific RFTYPE_* flags
251 * @seq_show: Show content of the file
252 * @write: Write to the file
253 */
254 struct rftype {
255 char *name;
256 umode_t mode;
257 const struct kernfs_ops *kf_ops;
258 unsigned long flags;
259 unsigned long fflags;
260
261 int (*seq_show)(struct kernfs_open_file *of,
262 struct seq_file *sf, void *v);
263 /*
264 * write() is the generic write callback which maps directly to
265 * kernfs write operation and overrides all other operations.
266 * Maximum write size is determined by ->max_write_len.
267 */
268 ssize_t (*write)(struct kernfs_open_file *of,
269 char *buf, size_t nbytes, loff_t off);
270 };
271
272 /**
273 * struct mbm_state - status for each MBM counter in each domain
274 * @prev_bw_bytes: Previous bytes value read for bandwidth calculation
275 * @prev_bw: The most recent bandwidth in MBps
276 */
277 struct mbm_state {
278 u64 prev_bw_bytes;
279 u32 prev_bw;
280 };
281
282 extern struct mutex rdtgroup_mutex;
283
rdt_kn_name(const struct kernfs_node * kn)284 static inline const char *rdt_kn_name(const struct kernfs_node *kn)
285 {
286 return rcu_dereference_check(kn->name, lockdep_is_held(&rdtgroup_mutex));
287 }
288
289 extern struct rdtgroup rdtgroup_default;
290
291 extern struct dentry *debugfs_resctrl;
292
293 extern enum resctrl_event_id mba_mbps_default_event;
294
295 void rdt_last_cmd_clear(void);
296
297 void rdt_last_cmd_puts(const char *s);
298
299 __printf(1, 2)
300 void rdt_last_cmd_printf(const char *fmt, ...);
301
302 struct rdtgroup *rdtgroup_kn_lock_live(struct kernfs_node *kn);
303
304 void rdtgroup_kn_unlock(struct kernfs_node *kn);
305
306 int rdtgroup_kn_mode_restrict(struct rdtgroup *r, const char *name);
307
308 int rdtgroup_kn_mode_restore(struct rdtgroup *r, const char *name,
309 umode_t mask);
310
311 ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
312 char *buf, size_t nbytes, loff_t off);
313
314 int rdtgroup_schemata_show(struct kernfs_open_file *of,
315 struct seq_file *s, void *v);
316
317 ssize_t rdtgroup_mba_mbps_event_write(struct kernfs_open_file *of,
318 char *buf, size_t nbytes, loff_t off);
319
320 int rdtgroup_mba_mbps_event_show(struct kernfs_open_file *of,
321 struct seq_file *s, void *v);
322
323 bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_ctrl_domain *d,
324 unsigned long cbm, int closid, bool exclusive);
325
326 unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_ctrl_domain *d,
327 unsigned long cbm);
328
329 enum rdtgrp_mode rdtgroup_mode_by_closid(int closid);
330
331 int rdtgroup_tasks_assigned(struct rdtgroup *r);
332
333 int closids_supported(void);
334
335 void closid_free(int closid);
336
337 int alloc_rmid(u32 closid);
338
339 void free_rmid(u32 closid, u32 rmid);
340
341 void resctrl_mon_resource_exit(void);
342
343 void mon_event_count(void *info);
344
345 int rdtgroup_mondata_show(struct seq_file *m, void *arg);
346
347 void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
348 struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
349 cpumask_t *cpumask, int evtid, int first);
350
351 int resctrl_mon_resource_init(void);
352
353 void mbm_setup_overflow_handler(struct rdt_mon_domain *dom,
354 unsigned long delay_ms,
355 int exclude_cpu);
356
357 void mbm_handle_overflow(struct work_struct *work);
358
359 bool is_mba_sc(struct rdt_resource *r);
360
361 void cqm_setup_limbo_handler(struct rdt_mon_domain *dom, unsigned long delay_ms,
362 int exclude_cpu);
363
364 void cqm_handle_limbo(struct work_struct *work);
365
366 bool has_busy_rmid(struct rdt_mon_domain *d);
367
368 void __check_limbo(struct rdt_mon_domain *d, bool force_free);
369
370 void resctrl_file_fflags_init(const char *config, unsigned long fflags);
371
372 void rdt_staged_configs_clear(void);
373
374 bool closid_allocated(unsigned int closid);
375
376 int resctrl_find_cleanest_closid(void);
377
378 #ifdef CONFIG_RESCTRL_FS_PSEUDO_LOCK
379 int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp);
380
381 int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp);
382
383 bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm);
384
385 bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d);
386
387 int rdt_pseudo_lock_init(void);
388
389 void rdt_pseudo_lock_release(void);
390
391 int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp);
392
393 void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp);
394
395 #else
rdtgroup_locksetup_enter(struct rdtgroup * rdtgrp)396 static inline int rdtgroup_locksetup_enter(struct rdtgroup *rdtgrp)
397 {
398 return -EOPNOTSUPP;
399 }
400
rdtgroup_locksetup_exit(struct rdtgroup * rdtgrp)401 static inline int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
402 {
403 return -EOPNOTSUPP;
404 }
405
rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain * d,unsigned long cbm)406 static inline bool rdtgroup_cbm_overlaps_pseudo_locked(struct rdt_ctrl_domain *d, unsigned long cbm)
407 {
408 return false;
409 }
410
rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain * d)411 static inline bool rdtgroup_pseudo_locked_in_hierarchy(struct rdt_ctrl_domain *d)
412 {
413 return false;
414 }
415
rdt_pseudo_lock_init(void)416 static inline int rdt_pseudo_lock_init(void) { return 0; }
rdt_pseudo_lock_release(void)417 static inline void rdt_pseudo_lock_release(void) { }
rdtgroup_pseudo_lock_create(struct rdtgroup * rdtgrp)418 static inline int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp)
419 {
420 return -EOPNOTSUPP;
421 }
422
rdtgroup_pseudo_lock_remove(struct rdtgroup * rdtgrp)423 static inline void rdtgroup_pseudo_lock_remove(struct rdtgroup *rdtgrp) { }
424 #endif /* CONFIG_RESCTRL_FS_PSEUDO_LOCK */
425
426 #endif /* _FS_RESCTRL_INTERNAL_H */
427