1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Resource Director Technology(RDT)
4 * - Monitoring code
5 *
6 * Copyright (C) 2017 Intel Corporation
7 *
8 * Author:
9 * Vikas Shivappa <vikas.shivappa@intel.com>
10 *
11 * This replaces the cqm.c based on perf but we reuse a lot of
12 * code and datastructures originally from Peter Zijlstra and Matt Fleming.
13 *
14 * More information about RDT be found in the Intel (R) x86 Architecture
15 * Software Developer Manual June 2016, volume 3, section 17.17.
16 */
17
18 #define pr_fmt(fmt) "resctrl: " fmt
19
20 #include <linux/cpu.h>
21 #include <linux/resctrl.h>
22 #include <linux/sizes.h>
23 #include <linux/slab.h>
24
25 #include "internal.h"
26
27 #define CREATE_TRACE_POINTS
28
29 #include "monitor_trace.h"
30
31 /**
32 * struct rmid_entry - dirty tracking for all RMID.
33 * @closid: The CLOSID for this entry.
34 * @rmid: The RMID for this entry.
35 * @busy: The number of domains with cached data using this RMID.
36 * @list: Member of the rmid_free_lru list when busy == 0.
37 *
38 * Depending on the architecture the correct monitor is accessed using
39 * both @closid and @rmid, or @rmid only.
40 *
41 * Take the rdtgroup_mutex when accessing.
42 */
43 struct rmid_entry {
44 u32 closid;
45 u32 rmid;
46 int busy;
47 struct list_head list;
48 };
49
50 /*
51 * @rmid_free_lru - A least recently used list of free RMIDs
52 * These RMIDs are guaranteed to have an occupancy less than the
53 * threshold occupancy
54 */
55 static LIST_HEAD(rmid_free_lru);
56
57 /*
58 * @closid_num_dirty_rmid The number of dirty RMID each CLOSID has.
59 * Only allocated when CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID is defined.
60 * Indexed by CLOSID. Protected by rdtgroup_mutex.
61 */
62 static u32 *closid_num_dirty_rmid;
63
64 /*
65 * @rmid_limbo_count - count of currently unused but (potentially)
66 * dirty RMIDs.
67 * This counts RMIDs that no one is currently using but that
68 * may have a occupancy value > resctrl_rmid_realloc_threshold. User can
69 * change the threshold occupancy value.
70 */
71 static unsigned int rmid_limbo_count;
72
73 /*
74 * @rmid_entry - The entry in the limbo and free lists.
75 */
76 static struct rmid_entry *rmid_ptrs;
77
78 /*
79 * This is the threshold cache occupancy in bytes at which we will consider an
80 * RMID available for re-allocation.
81 */
82 unsigned int resctrl_rmid_realloc_threshold;
83
84 /*
85 * This is the maximum value for the reallocation threshold, in bytes.
86 */
87 unsigned int resctrl_rmid_realloc_limit;
88
89 /*
90 * x86 and arm64 differ in their handling of monitoring.
91 * x86's RMID are independent numbers, there is only one source of traffic
92 * with an RMID value of '1'.
93 * arm64's PMG extends the PARTID/CLOSID space, there are multiple sources of
94 * traffic with a PMG value of '1', one for each CLOSID, meaning the RMID
95 * value is no longer unique.
96 * To account for this, resctrl uses an index. On x86 this is just the RMID,
97 * on arm64 it encodes the CLOSID and RMID. This gives a unique number.
98 *
99 * The domain's rmid_busy_llc and rmid_ptrs[] are sized by index. The arch code
100 * must accept an attempt to read every index.
101 */
__rmid_entry(u32 idx)102 static inline struct rmid_entry *__rmid_entry(u32 idx)
103 {
104 struct rmid_entry *entry;
105 u32 closid, rmid;
106
107 entry = &rmid_ptrs[idx];
108 resctrl_arch_rmid_idx_decode(idx, &closid, &rmid);
109
110 WARN_ON_ONCE(entry->closid != closid);
111 WARN_ON_ONCE(entry->rmid != rmid);
112
113 return entry;
114 }
115
limbo_release_entry(struct rmid_entry * entry)116 static void limbo_release_entry(struct rmid_entry *entry)
117 {
118 lockdep_assert_held(&rdtgroup_mutex);
119
120 rmid_limbo_count--;
121 list_add_tail(&entry->list, &rmid_free_lru);
122
123 if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
124 closid_num_dirty_rmid[entry->closid]--;
125 }
126
127 /*
128 * Check the RMIDs that are marked as busy for this domain. If the
129 * reported LLC occupancy is below the threshold clear the busy bit and
130 * decrement the count. If the busy count gets to zero on an RMID, we
131 * free the RMID
132 */
__check_limbo(struct rdt_l3_mon_domain * d,bool force_free)133 void __check_limbo(struct rdt_l3_mon_domain *d, bool force_free)
134 {
135 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
136 u32 idx_limit = resctrl_arch_system_num_rmid_idx();
137 struct rmid_entry *entry;
138 bool rmid_dirty = true;
139 u32 idx, cur_idx = 1;
140 void *arch_mon_ctx;
141 void *arch_priv;
142 u64 val = 0;
143
144 arch_priv = mon_event_all[QOS_L3_OCCUP_EVENT_ID].arch_priv;
145 arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, QOS_L3_OCCUP_EVENT_ID);
146 if (IS_ERR(arch_mon_ctx)) {
147 pr_warn_ratelimited("Failed to allocate monitor context: %pe",
148 arch_mon_ctx);
149 return;
150 }
151
152 /*
153 * Skip RMID 0 and start from RMID 1 and check all the RMIDs that
154 * are marked as busy for occupancy < threshold. If the occupancy
155 * is less than the threshold decrement the busy counter of the
156 * RMID and move it to the free list when the counter reaches 0.
157 */
158 for (;;) {
159 idx = find_next_bit(d->rmid_busy_llc, idx_limit, cur_idx);
160 if (idx >= idx_limit)
161 break;
162
163 entry = __rmid_entry(idx);
164 if (!force_free) {
165 if (resctrl_arch_rmid_read(r, &d->hdr, entry->closid,
166 entry->rmid, QOS_L3_OCCUP_EVENT_ID,
167 arch_priv, &val, arch_mon_ctx)) {
168 rmid_dirty = true;
169 } else {
170 rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
171
172 /*
173 * x86's CLOSID and RMID are independent numbers,
174 * so the entry's CLOSID is an empty CLOSID
175 * (X86_RESCTRL_EMPTY_CLOSID). On Arm the RMID
176 * (PMG) extends the CLOSID (PARTID) space with
177 * bits that aren't used to select the configuration.
178 * It is thus necessary to track both CLOSID and
179 * RMID because there may be dependencies between
180 * them on some architectures.
181 */
182 trace_mon_llc_occupancy_limbo(entry->closid, entry->rmid,
183 d->hdr.id, val);
184 }
185 }
186
187 if (force_free || !rmid_dirty) {
188 clear_bit(idx, d->rmid_busy_llc);
189 if (!--entry->busy)
190 limbo_release_entry(entry);
191 }
192 cur_idx = idx + 1;
193 }
194
195 resctrl_arch_mon_ctx_free(r, QOS_L3_OCCUP_EVENT_ID, arch_mon_ctx);
196 }
197
has_busy_rmid(struct rdt_l3_mon_domain * d)198 bool has_busy_rmid(struct rdt_l3_mon_domain *d)
199 {
200 u32 idx_limit = resctrl_arch_system_num_rmid_idx();
201
202 return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
203 }
204
resctrl_find_free_rmid(u32 closid)205 static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
206 {
207 struct rmid_entry *itr;
208 u32 itr_idx, cmp_idx;
209
210 if (list_empty(&rmid_free_lru))
211 return rmid_limbo_count ? ERR_PTR(-EBUSY) : ERR_PTR(-ENOSPC);
212
213 list_for_each_entry(itr, &rmid_free_lru, list) {
214 /*
215 * Get the index of this free RMID, and the index it would need
216 * to be if it were used with this CLOSID.
217 * If the CLOSID is irrelevant on this architecture, the two
218 * index values are always the same on every entry and thus the
219 * very first entry will be returned.
220 */
221 itr_idx = resctrl_arch_rmid_idx_encode(itr->closid, itr->rmid);
222 cmp_idx = resctrl_arch_rmid_idx_encode(closid, itr->rmid);
223
224 if (itr_idx == cmp_idx)
225 return itr;
226 }
227
228 return ERR_PTR(-ENOSPC);
229 }
230
231 /**
232 * resctrl_find_cleanest_closid() - Find a CLOSID where all the associated
233 * RMID are clean, or the CLOSID that has
234 * the most clean RMID.
235 *
236 * MPAM's equivalent of RMID are per-CLOSID, meaning a freshly allocated CLOSID
237 * may not be able to allocate clean RMID. To avoid this the allocator will
238 * choose the CLOSID with the most clean RMID.
239 *
240 * When the CLOSID and RMID are independent numbers, the first free CLOSID will
241 * be returned.
242 *
243 * Return: Free CLOSID on success, < 0 on failure.
244 */
resctrl_find_cleanest_closid(void)245 int resctrl_find_cleanest_closid(void)
246 {
247 u32 cleanest_closid = ~0;
248 int i = 0;
249
250 lockdep_assert_held(&rdtgroup_mutex);
251
252 if (!IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
253 return -EIO;
254
255 for (i = 0; i < closids_supported(); i++) {
256 int num_dirty;
257
258 if (closid_allocated(i))
259 continue;
260
261 num_dirty = closid_num_dirty_rmid[i];
262 if (num_dirty == 0)
263 return i;
264
265 if (cleanest_closid == ~0)
266 cleanest_closid = i;
267
268 if (num_dirty < closid_num_dirty_rmid[cleanest_closid])
269 cleanest_closid = i;
270 }
271
272 if (cleanest_closid == ~0)
273 return -ENOSPC;
274
275 return cleanest_closid;
276 }
277
278 /*
279 * For MPAM the RMID value is not unique, and has to be considered with
280 * the CLOSID. The (CLOSID, RMID) pair is allocated on all domains, which
281 * allows all domains to be managed by a single free list.
282 * Each domain also has a rmid_busy_llc to reduce the work of the limbo handler.
283 */
alloc_rmid(u32 closid)284 int alloc_rmid(u32 closid)
285 {
286 struct rmid_entry *entry;
287
288 lockdep_assert_held(&rdtgroup_mutex);
289
290 entry = resctrl_find_free_rmid(closid);
291 if (IS_ERR(entry))
292 return PTR_ERR(entry);
293
294 list_del(&entry->list);
295 return entry->rmid;
296 }
297
add_rmid_to_limbo(struct rmid_entry * entry)298 static void add_rmid_to_limbo(struct rmid_entry *entry)
299 {
300 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
301 struct rdt_l3_mon_domain *d;
302 u32 idx;
303
304 lockdep_assert_held(&rdtgroup_mutex);
305
306 /* Walking r->domains, ensure it can't race with cpuhp */
307 lockdep_assert_cpus_held();
308
309 idx = resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid);
310
311 entry->busy = 0;
312 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
313 /*
314 * For the first limbo RMID in the domain,
315 * setup up the limbo worker.
316 */
317 if (!has_busy_rmid(d))
318 cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL,
319 RESCTRL_PICK_ANY_CPU);
320 set_bit(idx, d->rmid_busy_llc);
321 entry->busy++;
322 }
323
324 rmid_limbo_count++;
325 if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
326 closid_num_dirty_rmid[entry->closid]++;
327 }
328
free_rmid(u32 closid,u32 rmid)329 void free_rmid(u32 closid, u32 rmid)
330 {
331 u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
332 struct rmid_entry *entry;
333
334 lockdep_assert_held(&rdtgroup_mutex);
335
336 /*
337 * Do not allow the default rmid to be free'd. Comparing by index
338 * allows architectures that ignore the closid parameter to avoid an
339 * unnecessary check.
340 */
341 if (!resctrl_arch_mon_capable() ||
342 idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
343 RESCTRL_RESERVED_RMID))
344 return;
345
346 entry = __rmid_entry(idx);
347
348 if (resctrl_is_mon_event_enabled(QOS_L3_OCCUP_EVENT_ID))
349 add_rmid_to_limbo(entry);
350 else
351 list_add_tail(&entry->list, &rmid_free_lru);
352 }
353
get_mbm_state(struct rdt_l3_mon_domain * d,u32 closid,u32 rmid,enum resctrl_event_id evtid)354 static struct mbm_state *get_mbm_state(struct rdt_l3_mon_domain *d, u32 closid,
355 u32 rmid, enum resctrl_event_id evtid)
356 {
357 u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
358 struct mbm_state *state;
359
360 if (!resctrl_is_mbm_event(evtid))
361 return NULL;
362
363 state = d->mbm_states[MBM_STATE_IDX(evtid)];
364
365 return state ? &state[idx] : NULL;
366 }
367
368 /*
369 * mbm_cntr_get() - Return the counter ID for the matching @evtid and @rdtgrp.
370 *
371 * Return:
372 * Valid counter ID on success, or -ENOENT on failure.
373 */
mbm_cntr_get(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,enum resctrl_event_id evtid)374 static int mbm_cntr_get(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
375 struct rdtgroup *rdtgrp, enum resctrl_event_id evtid)
376 {
377 int cntr_id;
378
379 if (!r->mon.mbm_cntr_assignable)
380 return -ENOENT;
381
382 if (!resctrl_is_mbm_event(evtid))
383 return -ENOENT;
384
385 for (cntr_id = 0; cntr_id < r->mon.num_mbm_cntrs; cntr_id++) {
386 if (d->cntr_cfg[cntr_id].rdtgrp == rdtgrp &&
387 d->cntr_cfg[cntr_id].evtid == evtid)
388 return cntr_id;
389 }
390
391 return -ENOENT;
392 }
393
394 /*
395 * mbm_cntr_alloc() - Initialize and return a new counter ID in the domain @d.
396 * Caller must ensure that the specified event is not assigned already.
397 *
398 * Return:
399 * Valid counter ID on success, or -ENOSPC on failure.
400 */
mbm_cntr_alloc(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,enum resctrl_event_id evtid)401 static int mbm_cntr_alloc(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
402 struct rdtgroup *rdtgrp, enum resctrl_event_id evtid)
403 {
404 int cntr_id;
405
406 for (cntr_id = 0; cntr_id < r->mon.num_mbm_cntrs; cntr_id++) {
407 if (!d->cntr_cfg[cntr_id].rdtgrp) {
408 d->cntr_cfg[cntr_id].rdtgrp = rdtgrp;
409 d->cntr_cfg[cntr_id].evtid = evtid;
410 return cntr_id;
411 }
412 }
413
414 return -ENOSPC;
415 }
416
417 /*
418 * mbm_cntr_free() - Clear the counter ID configuration details in the domain @d.
419 */
mbm_cntr_free(struct rdt_l3_mon_domain * d,int cntr_id)420 static void mbm_cntr_free(struct rdt_l3_mon_domain *d, int cntr_id)
421 {
422 memset(&d->cntr_cfg[cntr_id], 0, sizeof(*d->cntr_cfg));
423 }
424
__l3_mon_event_count(struct rdtgroup * rdtgrp,struct rmid_read * rr)425 static int __l3_mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
426 {
427 int cpu = smp_processor_id();
428 u32 closid = rdtgrp->closid;
429 u32 rmid = rdtgrp->mon.rmid;
430 struct rdt_l3_mon_domain *d;
431 int cntr_id = -ENOENT;
432 struct mbm_state *m;
433 u64 tval = 0;
434
435 if (!domain_header_is_valid(rr->hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3)) {
436 rr->err = -EIO;
437 return -EINVAL;
438 }
439 d = container_of(rr->hdr, struct rdt_l3_mon_domain, hdr);
440
441 if (rr->is_mbm_cntr) {
442 cntr_id = mbm_cntr_get(rr->r, d, rdtgrp, rr->evt->evtid);
443 if (cntr_id < 0) {
444 rr->err = -ENOENT;
445 return -EINVAL;
446 }
447 }
448
449 if (rr->first) {
450 if (rr->is_mbm_cntr)
451 resctrl_arch_reset_cntr(rr->r, d, closid, rmid, cntr_id, rr->evt->evtid);
452 else
453 resctrl_arch_reset_rmid(rr->r, d, closid, rmid, rr->evt->evtid);
454 m = get_mbm_state(d, closid, rmid, rr->evt->evtid);
455 if (m)
456 memset(m, 0, sizeof(struct mbm_state));
457 return 0;
458 }
459
460 /* Reading a single domain, must be on a CPU in that domain. */
461 if (!cpumask_test_cpu(cpu, &d->hdr.cpu_mask)) {
462 rr->err = -EIO;
463 return -EINVAL;
464 }
465 if (rr->is_mbm_cntr)
466 rr->err = resctrl_arch_cntr_read(rr->r, d, closid, rmid, cntr_id,
467 rr->evt->evtid, &tval);
468 else
469 rr->err = resctrl_arch_rmid_read(rr->r, rr->hdr, closid, rmid,
470 rr->evt->evtid, rr->evt->arch_priv,
471 &tval, rr->arch_mon_ctx);
472 if (rr->err)
473 return rr->err;
474
475 rr->val += tval;
476
477 return 0;
478 }
479
__l3_mon_event_count_sum(struct rdtgroup * rdtgrp,struct rmid_read * rr)480 static int __l3_mon_event_count_sum(struct rdtgroup *rdtgrp, struct rmid_read *rr)
481 {
482 int cpu = smp_processor_id();
483 u32 closid = rdtgrp->closid;
484 u32 rmid = rdtgrp->mon.rmid;
485 struct rdt_l3_mon_domain *d;
486 u64 tval = 0;
487 int err, ret;
488
489 /*
490 * Summing across domains is only done for systems that implement
491 * Sub-NUMA Cluster. There is no overlap with systems that support
492 * assignable counters.
493 */
494 if (rr->is_mbm_cntr) {
495 pr_warn_once("Summing domains using assignable counters is not supported\n");
496 rr->err = -EINVAL;
497 return -EINVAL;
498 }
499
500 /* Summing domains that share a cache, must be on a CPU for that cache. */
501 if (!cpumask_test_cpu(cpu, &rr->ci->shared_cpu_map)) {
502 rr->err = -EIO;
503 return -EINVAL;
504 }
505
506 /*
507 * Legacy files must report the sum of an event across all
508 * domains that share the same L3 cache instance.
509 * Report success if a read from any domain succeeds, -EINVAL
510 * (translated to "Unavailable" for user space) if reading from
511 * all domains fail for any reason.
512 */
513 ret = -EINVAL;
514 /*
515 * RCU list being traversed with CPU hotplug lock held. lockdep
516 * unable to help prove this here since this work is scheduled via
517 * smp_call*(). Not called from MBM overflow handler.
518 */
519 list_for_each_entry(d, &rr->r->mon_domains, hdr.list) {
520 if (d->ci_id != rr->ci->id)
521 continue;
522 err = resctrl_arch_rmid_read(rr->r, &d->hdr, closid, rmid,
523 rr->evt->evtid, rr->evt->arch_priv,
524 &tval, rr->arch_mon_ctx);
525 if (!err) {
526 rr->val += tval;
527 ret = 0;
528 }
529 }
530
531 if (ret)
532 rr->err = ret;
533
534 return ret;
535 }
536
__mon_event_count(struct rdtgroup * rdtgrp,struct rmid_read * rr)537 static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
538 {
539 switch (rr->r->rid) {
540 case RDT_RESOURCE_L3:
541 WARN_ON_ONCE(rr->evt->any_cpu);
542 if (rr->hdr)
543 return __l3_mon_event_count(rdtgrp, rr);
544 else
545 return __l3_mon_event_count_sum(rdtgrp, rr);
546 case RDT_RESOURCE_PERF_PKG: {
547 u64 tval = 0;
548
549 rr->err = resctrl_arch_rmid_read(rr->r, rr->hdr, rdtgrp->closid,
550 rdtgrp->mon.rmid, rr->evt->evtid,
551 rr->evt->arch_priv,
552 &tval, rr->arch_mon_ctx);
553 if (rr->err)
554 return rr->err;
555
556 rr->val += tval;
557
558 return 0;
559 }
560 default:
561 rr->err = -EINVAL;
562 return -EINVAL;
563 }
564 }
565
566 /*
567 * mbm_bw_count() - Update bw count from values previously read by
568 * __mon_event_count().
569 * @rdtgrp: resctrl group associated with the CLOSID and RMID to identify
570 * the cached mbm_state.
571 * @rr: The struct rmid_read populated by __mon_event_count().
572 *
573 * Supporting function to calculate the memory bandwidth
574 * and delta bandwidth in MBps. The chunks value previously read by
575 * __mon_event_count() is compared with the chunks value from the previous
576 * invocation. This must be called once per second to maintain values in MBps.
577 */
mbm_bw_count(struct rdtgroup * rdtgrp,struct rmid_read * rr)578 static void mbm_bw_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
579 {
580 u64 cur_bw, bytes, cur_bytes;
581 u32 closid = rdtgrp->closid;
582 u32 rmid = rdtgrp->mon.rmid;
583 struct rdt_l3_mon_domain *d;
584 struct mbm_state *m;
585
586 if (!domain_header_is_valid(rr->hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
587 return;
588 d = container_of(rr->hdr, struct rdt_l3_mon_domain, hdr);
589 m = get_mbm_state(d, closid, rmid, rr->evt->evtid);
590 if (WARN_ON_ONCE(!m))
591 return;
592
593 cur_bytes = rr->val;
594 bytes = cur_bytes - m->prev_bw_bytes;
595 m->prev_bw_bytes = cur_bytes;
596
597 cur_bw = bytes / SZ_1M;
598
599 m->prev_bw = cur_bw;
600 }
601
602 /*
603 * This is scheduled by mon_event_read() to read the CQM/MBM counters
604 * on a domain.
605 */
mon_event_count(void * info)606 void mon_event_count(void *info)
607 {
608 struct rdtgroup *rdtgrp, *entry;
609 struct rmid_read *rr = info;
610 struct list_head *head;
611 int ret;
612
613 rdtgrp = rr->rgrp;
614
615 ret = __mon_event_count(rdtgrp, rr);
616
617 /*
618 * For Ctrl groups read data from child monitor groups and
619 * add them together. Count events which are read successfully.
620 * Discard the rmid_read's reporting errors.
621 */
622 head = &rdtgrp->mon.crdtgrp_list;
623
624 if (rdtgrp->type == RDTCTRL_GROUP) {
625 list_for_each_entry(entry, head, mon.crdtgrp_list) {
626 if (__mon_event_count(entry, rr) == 0)
627 ret = 0;
628 }
629 }
630
631 /*
632 * __mon_event_count() calls for newly created monitor groups may
633 * report -EINVAL/Unavailable if the monitor hasn't seen any traffic.
634 * Discard error if any of the monitor event reads succeeded.
635 */
636 if (ret == 0)
637 rr->err = 0;
638 }
639
640 /*
641 * Find the software controller's ctrl domain that contains @cpu on resource @r.
642 *
643 * Only called from the mbm_over worker via update_mba_bw() where the returned
644 * domain is kept alive by cancel_delayed_work_sync() in
645 * resctrl_offline_ctrl_domain(). This drains this worker and then waits on
646 * rdtgroup_mutex held here before the architecture can free the ctrl domain.
647 *
648 * Context: Call from RCU read-side critical section.
649 */
get_sc_ctrl_domain_from_cpu(int cpu,struct rdt_resource * r)650 static struct rdt_ctrl_domain *get_sc_ctrl_domain_from_cpu(int cpu,
651 struct rdt_resource *r)
652 {
653 struct rdt_ctrl_domain *d;
654
655 list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list) {
656 /* Find the domain that contains this CPU */
657 if (cpumask_test_cpu(cpu, &d->hdr.cpu_mask))
658 return d;
659 }
660
661 return NULL;
662 }
663
664 /*
665 * Feedback loop for MBA software controller (mba_sc)
666 *
667 * mba_sc is a feedback loop where we periodically read MBM counters and
668 * adjust the bandwidth percentage values via the IA32_MBA_THRTL_MSRs so
669 * that:
670 *
671 * current bandwidth(cur_bw) < user specified bandwidth(user_bw)
672 *
673 * This uses the MBM counters to measure the bandwidth and MBA throttle
674 * MSRs to control the bandwidth for a particular rdtgrp. It builds on the
675 * fact that resctrl rdtgroups have both monitoring and control.
676 *
677 * The frequency of the checks is 1s and we just tag along the MBM overflow
678 * timer. Having 1s interval makes the calculation of bandwidth simpler.
679 *
680 * Although MBA's goal is to restrict the bandwidth to a maximum, there may
681 * be a need to increase the bandwidth to avoid unnecessarily restricting
682 * the L2 <-> L3 traffic.
683 *
684 * Since MBA controls the L2 external bandwidth where as MBM measures the
685 * L3 external bandwidth the following sequence could lead to such a
686 * situation.
687 *
688 * Consider an rdtgroup which had high L3 <-> memory traffic in initial
689 * phases -> mba_sc kicks in and reduced bandwidth percentage values -> but
690 * after some time rdtgroup has mostly L2 <-> L3 traffic.
691 *
692 * In this case we may restrict the rdtgroup's L2 <-> L3 traffic as its
693 * throttle MSRs already have low percentage values. To avoid
694 * unnecessarily restricting such rdtgroups, we also increase the bandwidth.
695 */
update_mba_bw(struct rdtgroup * rgrp,struct rdt_l3_mon_domain * dom_mbm)696 static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_l3_mon_domain *dom_mbm)
697 {
698 u32 closid, rmid, cur_msr_val, new_msr_val;
699 struct mbm_state *pmbm_data, *cmbm_data;
700 struct rdt_ctrl_domain *dom_mba;
701 enum resctrl_event_id evt_id;
702 struct rdt_resource *r_mba;
703 struct list_head *head;
704 struct rdtgroup *entry;
705 u32 cur_bw, user_bw;
706
707 r_mba = resctrl_arch_get_resource(RDT_RESOURCE_MBA);
708 evt_id = rgrp->mba_mbps_event;
709
710 closid = rgrp->closid;
711 rmid = rgrp->mon.rmid;
712 pmbm_data = get_mbm_state(dom_mbm, closid, rmid, evt_id);
713 if (WARN_ON_ONCE(!pmbm_data))
714 return;
715
716 guard(rcu)();
717 dom_mba = get_sc_ctrl_domain_from_cpu(smp_processor_id(), r_mba);
718 if (!dom_mba) {
719 pr_warn_once("Failure to get domain for MBA update\n");
720 return;
721 }
722
723 cur_bw = pmbm_data->prev_bw;
724 user_bw = dom_mba->mbps_val[closid];
725
726 /* MBA resource doesn't support CDP */
727 cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
728
729 /*
730 * For Ctrl groups read data from child monitor groups.
731 */
732 head = &rgrp->mon.crdtgrp_list;
733 list_for_each_entry(entry, head, mon.crdtgrp_list) {
734 cmbm_data = get_mbm_state(dom_mbm, entry->closid, entry->mon.rmid, evt_id);
735 if (WARN_ON_ONCE(!cmbm_data))
736 return;
737 cur_bw += cmbm_data->prev_bw;
738 }
739
740 /*
741 * Scale up/down the bandwidth linearly for the ctrl group. The
742 * bandwidth step is the bandwidth granularity specified by the
743 * hardware.
744 * Always increase throttling if current bandwidth is above the
745 * target set by user.
746 * But avoid thrashing up and down on every poll by checking
747 * whether a decrease in throttling is likely to push the group
748 * back over target. E.g. if currently throttling to 30% of bandwidth
749 * on a system with 10% granularity steps, check whether moving to
750 * 40% would go past the limit by multiplying current bandwidth by
751 * "(30 + 10) / 30".
752 */
753 if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) {
754 new_msr_val = cur_msr_val - r_mba->membw.bw_gran;
755 } else if (cur_msr_val < MAX_MBA_BW &&
756 (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) {
757 new_msr_val = cur_msr_val + r_mba->membw.bw_gran;
758 } else {
759 return;
760 }
761
762 resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
763 }
764
mbm_update_one_event(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,enum resctrl_event_id evtid)765 static void mbm_update_one_event(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
766 struct rdtgroup *rdtgrp, enum resctrl_event_id evtid)
767 {
768 struct rmid_read rr = {0};
769
770 rr.r = r;
771 rr.hdr = &d->hdr;
772 rr.evt = &mon_event_all[evtid];
773 if (resctrl_arch_mbm_cntr_assign_enabled(r)) {
774 rr.is_mbm_cntr = true;
775 } else {
776 rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, evtid);
777 if (IS_ERR(rr.arch_mon_ctx)) {
778 pr_warn_ratelimited("Failed to allocate monitor context: %pe",
779 rr.arch_mon_ctx);
780 return;
781 }
782 }
783
784 __mon_event_count(rdtgrp, &rr);
785
786 /*
787 * If the software controller is enabled, compute the
788 * bandwidth for this event id.
789 */
790 if (is_mba_sc(NULL))
791 mbm_bw_count(rdtgrp, &rr);
792
793 if (rr.arch_mon_ctx)
794 resctrl_arch_mon_ctx_free(rr.r, evtid, rr.arch_mon_ctx);
795 }
796
mbm_update(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp)797 static void mbm_update(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
798 struct rdtgroup *rdtgrp)
799 {
800 /*
801 * This is protected from concurrent reads from user as both
802 * the user and overflow handler hold the global mutex.
803 */
804 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
805 mbm_update_one_event(r, d, rdtgrp, QOS_L3_MBM_TOTAL_EVENT_ID);
806
807 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
808 mbm_update_one_event(r, d, rdtgrp, QOS_L3_MBM_LOCAL_EVENT_ID);
809 }
810
811 /*
812 * Handler to scan the limbo list and move the RMIDs
813 * to free list whose occupancy < threshold_occupancy.
814 */
cqm_handle_limbo(struct work_struct * work)815 void cqm_handle_limbo(struct work_struct *work)
816 {
817 unsigned long delay = msecs_to_jiffies(CQM_LIMBOCHECK_INTERVAL);
818 struct rdt_l3_mon_domain *d;
819
820 /*
821 * Safe to run without CPU hotplug lock. Work is guaranteed to be
822 * canceled before the domain structure is removed.
823 */
824 mutex_lock(&rdtgroup_mutex);
825
826 /*
827 * Ensure the worker is dedicated to a CPU as intended and not
828 * relocated by workqueue subsystem as part of CPU going offline.
829 */
830 if (!is_percpu_thread())
831 goto out_unlock;
832
833 d = container_of(work, struct rdt_l3_mon_domain, cqm_limbo.work);
834
835 /* Domain is going offline */
836 if (cpumask_empty(&d->hdr.cpu_mask))
837 goto out_unlock;
838
839 __check_limbo(d, false);
840
841 if (has_busy_rmid(d)) {
842 d->cqm_work_cpu = cpumask_any_housekeeping(&d->hdr.cpu_mask,
843 RESCTRL_PICK_ANY_CPU);
844 schedule_delayed_work_on(d->cqm_work_cpu, &d->cqm_limbo,
845 delay);
846 }
847
848 out_unlock:
849 mutex_unlock(&rdtgroup_mutex);
850 }
851
852 /**
853 * cqm_setup_limbo_handler() - Schedule the limbo handler to run for this
854 * domain.
855 * @dom: The domain the limbo handler should run for.
856 * @delay_ms: How far in the future the handler should run.
857 * @exclude_cpu: Which CPU the handler should not run on,
858 * RESCTRL_PICK_ANY_CPU to pick any CPU.
859 */
cqm_setup_limbo_handler(struct rdt_l3_mon_domain * dom,unsigned long delay_ms,int exclude_cpu)860 void cqm_setup_limbo_handler(struct rdt_l3_mon_domain *dom, unsigned long delay_ms,
861 int exclude_cpu)
862 {
863 unsigned long delay = msecs_to_jiffies(delay_ms);
864 int cpu;
865
866 cpu = cpumask_any_housekeeping(&dom->hdr.cpu_mask, exclude_cpu);
867 dom->cqm_work_cpu = cpu;
868
869 if (cpu < nr_cpu_ids)
870 schedule_delayed_work_on(cpu, &dom->cqm_limbo, delay);
871 }
872
mbm_handle_overflow(struct work_struct * work)873 void mbm_handle_overflow(struct work_struct *work)
874 {
875 unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL);
876 struct rdtgroup *prgrp, *crgrp;
877 struct rdt_l3_mon_domain *d;
878 struct list_head *head;
879 struct rdt_resource *r;
880
881 /*
882 * Safe to run without CPU hotplug lock. Work is guaranteed to be
883 * canceled before the domain structure is removed.
884 */
885 mutex_lock(&rdtgroup_mutex);
886
887 /*
888 * If the filesystem has been unmounted this work no longer needs to
889 * run.
890 */
891 if (!resctrl_mounted || !resctrl_arch_mon_capable())
892 goto out_unlock;
893
894 /*
895 * Ensure the worker is dedicated to a CPU and not relocated by
896 * workqueue subsystem as part of CPU going offline since reading
897 * events depend on smp_processor_id(). After passing this check
898 * smp_processor_id() is valid for entire duration of this worker
899 * since it runs with rdtgroup_mutex held and the offline handler needs
900 * rdtgroup_mutex to offline the CPU being run on here.
901 */
902 if (!is_percpu_thread())
903 goto out_unlock;
904
905 r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
906 d = container_of(work, struct rdt_l3_mon_domain, mbm_over.work);
907
908 /* Domain is going offline */
909 if (cpumask_empty(&d->hdr.cpu_mask))
910 goto out_unlock;
911
912 list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
913 mbm_update(r, d, prgrp);
914
915 head = &prgrp->mon.crdtgrp_list;
916 list_for_each_entry(crgrp, head, mon.crdtgrp_list)
917 mbm_update(r, d, crgrp);
918
919 if (is_mba_sc(NULL))
920 update_mba_bw(prgrp, d);
921 }
922
923 /*
924 * Re-check for housekeeping CPUs. This allows the overflow handler to
925 * move off a nohz_full CPU quickly.
926 */
927 d->mbm_work_cpu = cpumask_any_housekeeping(&d->hdr.cpu_mask,
928 RESCTRL_PICK_ANY_CPU);
929 schedule_delayed_work_on(d->mbm_work_cpu, &d->mbm_over, delay);
930
931 out_unlock:
932 mutex_unlock(&rdtgroup_mutex);
933 }
934
935 /**
936 * mbm_setup_overflow_handler() - Schedule the overflow handler to run for this
937 * domain.
938 * @dom: The domain the overflow handler should run for.
939 * @delay_ms: How far in the future the handler should run.
940 * @exclude_cpu: Which CPU the handler should not run on,
941 * RESCTRL_PICK_ANY_CPU to pick any CPU.
942 */
mbm_setup_overflow_handler(struct rdt_l3_mon_domain * dom,unsigned long delay_ms,int exclude_cpu)943 void mbm_setup_overflow_handler(struct rdt_l3_mon_domain *dom, unsigned long delay_ms,
944 int exclude_cpu)
945 {
946 unsigned long delay = msecs_to_jiffies(delay_ms);
947 int cpu;
948
949 /*
950 * When a domain comes online there is no guarantee the filesystem is
951 * mounted. If not, there is no need to catch counter overflow.
952 */
953 if (!resctrl_mounted || !resctrl_arch_mon_capable())
954 return;
955 cpu = cpumask_any_housekeeping(&dom->hdr.cpu_mask, exclude_cpu);
956 dom->mbm_work_cpu = cpu;
957
958 if (cpu < nr_cpu_ids)
959 schedule_delayed_work_on(cpu, &dom->mbm_over, delay);
960 }
961
setup_rmid_lru_list(void)962 int setup_rmid_lru_list(void)
963 {
964 struct rmid_entry *entry = NULL;
965 u32 idx_limit;
966 u32 idx;
967 int i;
968
969 if (!resctrl_arch_mon_capable())
970 return 0;
971
972 /*
973 * Called on every mount, but the number of RMIDs cannot change
974 * after the first mount, so keep using the same set of rmid_ptrs[]
975 * until resctrl_exit(). Note that the limbo handler continues to
976 * access rmid_ptrs[] after resctrl is unmounted.
977 */
978 if (rmid_ptrs)
979 return 0;
980
981 idx_limit = resctrl_arch_system_num_rmid_idx();
982 rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit);
983 if (!rmid_ptrs)
984 return -ENOMEM;
985
986 for (i = 0; i < idx_limit; i++) {
987 entry = &rmid_ptrs[i];
988 INIT_LIST_HEAD(&entry->list);
989
990 resctrl_arch_rmid_idx_decode(i, &entry->closid, &entry->rmid);
991 list_add_tail(&entry->list, &rmid_free_lru);
992 }
993
994 /*
995 * RESCTRL_RESERVED_CLOSID and RESCTRL_RESERVED_RMID are special and
996 * are always allocated. These are used for the rdtgroup_default
997 * control group, which was setup earlier in rdtgroup_setup_default().
998 */
999 idx = resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
1000 RESCTRL_RESERVED_RMID);
1001 entry = __rmid_entry(idx);
1002 list_del(&entry->list);
1003
1004 return 0;
1005 }
1006
free_rmid_lru_list(void)1007 void free_rmid_lru_list(void)
1008 {
1009 if (!resctrl_arch_mon_capable())
1010 return;
1011
1012 mutex_lock(&rdtgroup_mutex);
1013 kfree(rmid_ptrs);
1014 rmid_ptrs = NULL;
1015 mutex_unlock(&rdtgroup_mutex);
1016 }
1017
1018 #define MON_EVENT(_eventid, _name, _res, _fp) \
1019 [_eventid] = { \
1020 .name = _name, \
1021 .evtid = _eventid, \
1022 .rid = _res, \
1023 .is_floating_point = _fp, \
1024 }
1025
1026 /*
1027 * All available events. Architecture code marks the ones that
1028 * are supported by a system using resctrl_enable_mon_event()
1029 * to set .enabled.
1030 */
1031 struct mon_evt mon_event_all[QOS_NUM_EVENTS] = {
1032 MON_EVENT(QOS_L3_OCCUP_EVENT_ID, "llc_occupancy", RDT_RESOURCE_L3, false),
1033 MON_EVENT(QOS_L3_MBM_TOTAL_EVENT_ID, "mbm_total_bytes", RDT_RESOURCE_L3, false),
1034 MON_EVENT(QOS_L3_MBM_LOCAL_EVENT_ID, "mbm_local_bytes", RDT_RESOURCE_L3, false),
1035 MON_EVENT(PMT_EVENT_ENERGY, "core_energy", RDT_RESOURCE_PERF_PKG, true),
1036 MON_EVENT(PMT_EVENT_ACTIVITY, "activity", RDT_RESOURCE_PERF_PKG, true),
1037 MON_EVENT(PMT_EVENT_STALLS_LLC_HIT, "stalls_llc_hit", RDT_RESOURCE_PERF_PKG, false),
1038 MON_EVENT(PMT_EVENT_C1_RES, "c1_res", RDT_RESOURCE_PERF_PKG, false),
1039 MON_EVENT(PMT_EVENT_UNHALTED_CORE_CYCLES, "unhalted_core_cycles", RDT_RESOURCE_PERF_PKG, false),
1040 MON_EVENT(PMT_EVENT_STALLS_LLC_MISS, "stalls_llc_miss", RDT_RESOURCE_PERF_PKG, false),
1041 MON_EVENT(PMT_EVENT_AUTO_C6_RES, "c6_res", RDT_RESOURCE_PERF_PKG, false),
1042 MON_EVENT(PMT_EVENT_UNHALTED_REF_CYCLES, "unhalted_ref_cycles", RDT_RESOURCE_PERF_PKG, false),
1043 MON_EVENT(PMT_EVENT_UOPS_RETIRED, "uops_retired", RDT_RESOURCE_PERF_PKG, false),
1044 };
1045
resctrl_enable_mon_event(enum resctrl_event_id eventid,bool any_cpu,unsigned int binary_bits,void * arch_priv)1046 bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu,
1047 unsigned int binary_bits, void *arch_priv)
1048 {
1049 if (WARN_ON_ONCE(eventid < QOS_FIRST_EVENT || eventid >= QOS_NUM_EVENTS ||
1050 binary_bits > MAX_BINARY_BITS))
1051 return false;
1052 if (mon_event_all[eventid].enabled) {
1053 pr_warn("Duplicate enable for event %d\n", eventid);
1054 return false;
1055 }
1056 if (binary_bits && !mon_event_all[eventid].is_floating_point) {
1057 pr_warn("Event %d may not be floating point\n", eventid);
1058 return false;
1059 }
1060
1061 mon_event_all[eventid].any_cpu = any_cpu;
1062 mon_event_all[eventid].binary_bits = binary_bits;
1063 mon_event_all[eventid].arch_priv = arch_priv;
1064 mon_event_all[eventid].enabled = true;
1065
1066 return true;
1067 }
1068
resctrl_is_mon_event_enabled(enum resctrl_event_id eventid)1069 bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid)
1070 {
1071 return eventid >= QOS_FIRST_EVENT && eventid < QOS_NUM_EVENTS &&
1072 mon_event_all[eventid].enabled;
1073 }
1074
resctrl_get_mon_evt_cfg(enum resctrl_event_id evtid)1075 u32 resctrl_get_mon_evt_cfg(enum resctrl_event_id evtid)
1076 {
1077 return mon_event_all[evtid].evt_cfg;
1078 }
1079
1080 /**
1081 * struct mbm_transaction - Memory transaction an MBM event can be configured with.
1082 * @name: Name of memory transaction (read, write ...).
1083 * @val: The bit (eg. READS_TO_LOCAL_MEM or READS_TO_REMOTE_MEM) used to
1084 * represent the memory transaction within an event's configuration.
1085 */
1086 struct mbm_transaction {
1087 char name[32];
1088 u32 val;
1089 };
1090
1091 /* Decoded values for each type of memory transaction. */
1092 static struct mbm_transaction mbm_transactions[NUM_MBM_TRANSACTIONS] = {
1093 {"local_reads", READS_TO_LOCAL_MEM},
1094 {"remote_reads", READS_TO_REMOTE_MEM},
1095 {"local_non_temporal_writes", NON_TEMP_WRITE_TO_LOCAL_MEM},
1096 {"remote_non_temporal_writes", NON_TEMP_WRITE_TO_REMOTE_MEM},
1097 {"local_reads_slow_memory", READS_TO_LOCAL_S_MEM},
1098 {"remote_reads_slow_memory", READS_TO_REMOTE_S_MEM},
1099 {"dirty_victim_writes_all", DIRTY_VICTIMS_TO_ALL_MEM},
1100 };
1101
event_filter_show(struct kernfs_open_file * of,struct seq_file * seq,void * v)1102 int event_filter_show(struct kernfs_open_file *of, struct seq_file *seq, void *v)
1103 {
1104 struct mon_evt *mevt = rdt_kn_parent_priv(of->kn);
1105 struct rdt_resource *r;
1106 bool sep = false;
1107 int ret = 0, i;
1108
1109 if (!info_kn_lock(of->kn))
1110 return -ENOENT;
1111 rdt_last_cmd_clear();
1112
1113 r = resctrl_arch_get_resource(mevt->rid);
1114 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1115 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1116 ret = -EINVAL;
1117 goto out_unlock;
1118 }
1119
1120 for (i = 0; i < NUM_MBM_TRANSACTIONS; i++) {
1121 if (mevt->evt_cfg & mbm_transactions[i].val) {
1122 if (sep)
1123 seq_putc(seq, ',');
1124 seq_printf(seq, "%s", mbm_transactions[i].name);
1125 sep = true;
1126 }
1127 }
1128 seq_putc(seq, '\n');
1129
1130 out_unlock:
1131 info_kn_unlock(of->kn);
1132
1133 return ret;
1134 }
1135
resctrl_mbm_assign_on_mkdir_show(struct kernfs_open_file * of,struct seq_file * s,void * v)1136 int resctrl_mbm_assign_on_mkdir_show(struct kernfs_open_file *of, struct seq_file *s,
1137 void *v)
1138 {
1139 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1140 int ret = 0;
1141
1142 if (!info_kn_lock(of->kn))
1143 return -ENOENT;
1144 rdt_last_cmd_clear();
1145
1146 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1147 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1148 ret = -EINVAL;
1149 goto out_unlock;
1150 }
1151
1152 seq_printf(s, "%u\n", r->mon.mbm_assign_on_mkdir);
1153
1154 out_unlock:
1155 info_kn_unlock(of->kn);
1156
1157 return ret;
1158 }
1159
resctrl_mbm_assign_on_mkdir_write(struct kernfs_open_file * of,char * buf,size_t nbytes,loff_t off)1160 ssize_t resctrl_mbm_assign_on_mkdir_write(struct kernfs_open_file *of, char *buf,
1161 size_t nbytes, loff_t off)
1162 {
1163 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1164 bool value;
1165 int ret;
1166
1167 if (!info_kn_lock(of->kn))
1168 return -ENOENT;
1169 rdt_last_cmd_clear();
1170
1171 ret = kstrtobool(buf, &value);
1172 if (ret) {
1173 rdt_last_cmd_puts("mbm_assign_on_mkdir: Invalid input\n");
1174 goto out_unlock;
1175 }
1176
1177 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1178 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1179 ret = -EINVAL;
1180 goto out_unlock;
1181 }
1182
1183 r->mon.mbm_assign_on_mkdir = value;
1184
1185 out_unlock:
1186 info_kn_unlock(of->kn);
1187
1188 return ret ?: nbytes;
1189 }
1190
1191 /*
1192 * mbm_cntr_free_all() - Clear all the counter ID configuration details in the
1193 * domain @d. Called when mbm_assign_mode is changed.
1194 */
mbm_cntr_free_all(struct rdt_resource * r,struct rdt_l3_mon_domain * d)1195 static void mbm_cntr_free_all(struct rdt_resource *r, struct rdt_l3_mon_domain *d)
1196 {
1197 memset(d->cntr_cfg, 0, sizeof(*d->cntr_cfg) * r->mon.num_mbm_cntrs);
1198 }
1199
1200 /*
1201 * resctrl_reset_rmid_all() - Reset all non-architecture states for all the
1202 * supported RMIDs.
1203 */
resctrl_reset_rmid_all(struct rdt_resource * r,struct rdt_l3_mon_domain * d)1204 static void resctrl_reset_rmid_all(struct rdt_resource *r, struct rdt_l3_mon_domain *d)
1205 {
1206 u32 idx_limit = resctrl_arch_system_num_rmid_idx();
1207 enum resctrl_event_id evt;
1208 int idx;
1209
1210 for_each_mbm_event_id(evt) {
1211 if (!resctrl_is_mon_event_enabled(evt))
1212 continue;
1213 idx = MBM_STATE_IDX(evt);
1214 memset(d->mbm_states[idx], 0, sizeof(*d->mbm_states[0]) * idx_limit);
1215 }
1216 }
1217
1218 /*
1219 * rdtgroup_assign_cntr() - Assign/unassign the counter ID for the event, RMID
1220 * pair in the domain.
1221 *
1222 * Assign the counter if @assign is true else unassign the counter. Reset the
1223 * associated non-architectural state.
1224 */
rdtgroup_assign_cntr(struct rdt_resource * r,struct rdt_l3_mon_domain * d,enum resctrl_event_id evtid,u32 rmid,u32 closid,u32 cntr_id,bool assign)1225 static void rdtgroup_assign_cntr(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
1226 enum resctrl_event_id evtid, u32 rmid, u32 closid,
1227 u32 cntr_id, bool assign)
1228 {
1229 struct mbm_state *m;
1230
1231 resctrl_arch_config_cntr(r, d, evtid, rmid, closid, cntr_id, assign);
1232
1233 m = get_mbm_state(d, closid, rmid, evtid);
1234 if (m)
1235 memset(m, 0, sizeof(*m));
1236 }
1237
1238 /*
1239 * rdtgroup_alloc_assign_cntr() - Allocate a counter ID and assign it to the event
1240 * pointed to by @mevt and the resctrl group @rdtgrp within the domain @d.
1241 *
1242 * Return:
1243 * 0 on success, < 0 on failure.
1244 */
rdtgroup_alloc_assign_cntr(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,struct mon_evt * mevt)1245 static int rdtgroup_alloc_assign_cntr(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
1246 struct rdtgroup *rdtgrp, struct mon_evt *mevt)
1247 {
1248 int cntr_id;
1249
1250 /* No action required if the counter is assigned already. */
1251 cntr_id = mbm_cntr_get(r, d, rdtgrp, mevt->evtid);
1252 if (cntr_id >= 0)
1253 return 0;
1254
1255 cntr_id = mbm_cntr_alloc(r, d, rdtgrp, mevt->evtid);
1256 if (cntr_id < 0) {
1257 rdt_last_cmd_printf("Failed to allocate counter for %s in domain %d\n",
1258 mevt->name, d->hdr.id);
1259 return cntr_id;
1260 }
1261
1262 rdtgroup_assign_cntr(r, d, mevt->evtid, rdtgrp->mon.rmid, rdtgrp->closid, cntr_id, true);
1263
1264 return 0;
1265 }
1266
1267 /*
1268 * rdtgroup_assign_cntr_event() - Assign a hardware counter for the event in
1269 * @mevt to the resctrl group @rdtgrp. Assign counters to all domains if @d is
1270 * NULL; otherwise, assign the counter to the specified domain @d.
1271 *
1272 * If all counters in a domain are already in use, rdtgroup_alloc_assign_cntr()
1273 * will fail. When attempting to assign counters to all domains, carry on trying
1274 * to assign counters after a failure since only some domains may have counters
1275 * and the goal is to assign counters where possible. If any counter assignment
1276 * fails, return the error from the last failing assignment.
1277 *
1278 * Return:
1279 * 0 on success, < 0 on failure.
1280 */
rdtgroup_assign_cntr_event(struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,struct mon_evt * mevt)1281 static int rdtgroup_assign_cntr_event(struct rdt_l3_mon_domain *d, struct rdtgroup *rdtgrp,
1282 struct mon_evt *mevt)
1283 {
1284 struct rdt_resource *r = resctrl_arch_get_resource(mevt->rid);
1285 int ret = 0;
1286
1287 if (!d) {
1288 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1289 int err;
1290
1291 err = rdtgroup_alloc_assign_cntr(r, d, rdtgrp, mevt);
1292 if (err)
1293 ret = err;
1294 }
1295 } else {
1296 ret = rdtgroup_alloc_assign_cntr(r, d, rdtgrp, mevt);
1297 }
1298
1299 return ret;
1300 }
1301
1302 /*
1303 * rdtgroup_assign_cntrs() - Assign counters to MBM events. Called when
1304 * a new group is created.
1305 *
1306 * Each group can accommodate two counters per domain: one for the total
1307 * event and one for the local event. Assignments may fail due to the limited
1308 * number of counters. However, it is not necessary to fail the group creation
1309 * and thus no failure is returned. Users have the option to modify the
1310 * counter assignments after the group has been created.
1311 */
rdtgroup_assign_cntrs(struct rdtgroup * rdtgrp)1312 void rdtgroup_assign_cntrs(struct rdtgroup *rdtgrp)
1313 {
1314 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1315
1316 if (!r->mon_capable || !resctrl_arch_mbm_cntr_assign_enabled(r) ||
1317 !r->mon.mbm_assign_on_mkdir)
1318 return;
1319
1320 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
1321 rdtgroup_assign_cntr_event(NULL, rdtgrp,
1322 &mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID]);
1323
1324 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
1325 rdtgroup_assign_cntr_event(NULL, rdtgrp,
1326 &mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID]);
1327 }
1328
1329 /*
1330 * rdtgroup_free_unassign_cntr() - Unassign and reset the counter ID configuration
1331 * for the event pointed to by @mevt within the domain @d and resctrl group @rdtgrp.
1332 */
rdtgroup_free_unassign_cntr(struct rdt_resource * r,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,struct mon_evt * mevt)1333 static void rdtgroup_free_unassign_cntr(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
1334 struct rdtgroup *rdtgrp, struct mon_evt *mevt)
1335 {
1336 int cntr_id;
1337
1338 cntr_id = mbm_cntr_get(r, d, rdtgrp, mevt->evtid);
1339
1340 /* If there is no cntr_id assigned, nothing to do */
1341 if (cntr_id < 0)
1342 return;
1343
1344 rdtgroup_assign_cntr(r, d, mevt->evtid, rdtgrp->mon.rmid, rdtgrp->closid, cntr_id, false);
1345
1346 mbm_cntr_free(d, cntr_id);
1347 }
1348
1349 /*
1350 * rdtgroup_unassign_cntr_event() - Unassign a hardware counter associated with
1351 * the event structure @mevt from the domain @d and the group @rdtgrp. Unassign
1352 * the counters from all the domains if @d is NULL else unassign from @d.
1353 */
rdtgroup_unassign_cntr_event(struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,struct mon_evt * mevt)1354 static void rdtgroup_unassign_cntr_event(struct rdt_l3_mon_domain *d, struct rdtgroup *rdtgrp,
1355 struct mon_evt *mevt)
1356 {
1357 struct rdt_resource *r = resctrl_arch_get_resource(mevt->rid);
1358
1359 if (!d) {
1360 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held())
1361 rdtgroup_free_unassign_cntr(r, d, rdtgrp, mevt);
1362 } else {
1363 rdtgroup_free_unassign_cntr(r, d, rdtgrp, mevt);
1364 }
1365 }
1366
1367 /*
1368 * rdtgroup_unassign_cntrs() - Unassign the counters associated with MBM events.
1369 * Called when a group is deleted.
1370 */
rdtgroup_unassign_cntrs(struct rdtgroup * rdtgrp)1371 void rdtgroup_unassign_cntrs(struct rdtgroup *rdtgrp)
1372 {
1373 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1374
1375 if (!r->mon_capable || !resctrl_arch_mbm_cntr_assign_enabled(r))
1376 return;
1377
1378 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
1379 rdtgroup_unassign_cntr_event(NULL, rdtgrp,
1380 &mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID]);
1381
1382 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
1383 rdtgroup_unassign_cntr_event(NULL, rdtgrp,
1384 &mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID]);
1385 }
1386
resctrl_parse_mem_transactions(char * tok,u32 * val)1387 static int resctrl_parse_mem_transactions(char *tok, u32 *val)
1388 {
1389 u32 temp_val = 0;
1390 char *evt_str;
1391 bool found;
1392 int i;
1393
1394 next_config:
1395 if (!tok || tok[0] == '\0') {
1396 *val = temp_val;
1397 return 0;
1398 }
1399
1400 /* Start processing the strings for each memory transaction type */
1401 evt_str = strim(strsep(&tok, ","));
1402 found = false;
1403 for (i = 0; i < NUM_MBM_TRANSACTIONS; i++) {
1404 if (!strcmp(mbm_transactions[i].name, evt_str)) {
1405 temp_val |= mbm_transactions[i].val;
1406 found = true;
1407 break;
1408 }
1409 }
1410
1411 if (!found) {
1412 rdt_last_cmd_printf("Invalid memory transaction type %s\n", evt_str);
1413 return -EINVAL;
1414 }
1415
1416 goto next_config;
1417 }
1418
1419 /*
1420 * rdtgroup_update_cntr_event - Update the counter assignments for the event
1421 * in a group.
1422 * @r: Resource to which update needs to be done.
1423 * @rdtgrp: Resctrl group.
1424 * @evtid: MBM monitor event.
1425 */
rdtgroup_update_cntr_event(struct rdt_resource * r,struct rdtgroup * rdtgrp,enum resctrl_event_id evtid)1426 static void rdtgroup_update_cntr_event(struct rdt_resource *r, struct rdtgroup *rdtgrp,
1427 enum resctrl_event_id evtid)
1428 {
1429 struct rdt_l3_mon_domain *d;
1430 int cntr_id;
1431
1432 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1433 cntr_id = mbm_cntr_get(r, d, rdtgrp, evtid);
1434 if (cntr_id >= 0)
1435 rdtgroup_assign_cntr(r, d, evtid, rdtgrp->mon.rmid,
1436 rdtgrp->closid, cntr_id, true);
1437 }
1438 }
1439
1440 /*
1441 * resctrl_update_cntr_allrdtgrp - Update the counter assignments for the event
1442 * for all the groups.
1443 * @mevt MBM Monitor event.
1444 */
resctrl_update_cntr_allrdtgrp(struct mon_evt * mevt)1445 static void resctrl_update_cntr_allrdtgrp(struct mon_evt *mevt)
1446 {
1447 struct rdt_resource *r = resctrl_arch_get_resource(mevt->rid);
1448 struct rdtgroup *prgrp, *crgrp;
1449
1450 /*
1451 * Find all the groups where the event is assigned and update the
1452 * configuration of existing assignments.
1453 */
1454 list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
1455 rdtgroup_update_cntr_event(r, prgrp, mevt->evtid);
1456
1457 list_for_each_entry(crgrp, &prgrp->mon.crdtgrp_list, mon.crdtgrp_list)
1458 rdtgroup_update_cntr_event(r, crgrp, mevt->evtid);
1459 }
1460 }
1461
event_filter_write(struct kernfs_open_file * of,char * buf,size_t nbytes,loff_t off)1462 ssize_t event_filter_write(struct kernfs_open_file *of, char *buf, size_t nbytes,
1463 loff_t off)
1464 {
1465 struct mon_evt *mevt = rdt_kn_parent_priv(of->kn);
1466 struct rdt_resource *r;
1467 u32 evt_cfg = 0;
1468 int ret = 0;
1469
1470 if (!info_kn_lock(of->kn))
1471 return -ENOENT;
1472
1473 rdt_last_cmd_clear();
1474
1475 /* Valid input requires a trailing newline */
1476 if (nbytes == 0 || buf[nbytes - 1] != '\n') {
1477 rdt_last_cmd_puts("event_filter: Invalid input\n");
1478 ret = -EINVAL;
1479 goto out_unlock;
1480 }
1481
1482 buf[nbytes - 1] = '\0';
1483
1484 r = resctrl_arch_get_resource(mevt->rid);
1485 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1486 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1487 ret = -EINVAL;
1488 goto out_unlock;
1489 }
1490 if (!r->mon.mbm_cntr_configurable) {
1491 rdt_last_cmd_puts("event_filter is not configurable\n");
1492 ret = -EPERM;
1493 goto out_unlock;
1494 }
1495
1496 ret = resctrl_parse_mem_transactions(buf, &evt_cfg);
1497 if (!ret && mevt->evt_cfg != evt_cfg) {
1498 mevt->evt_cfg = evt_cfg;
1499 resctrl_update_cntr_allrdtgrp(mevt);
1500 }
1501
1502 out_unlock:
1503 info_kn_unlock(of->kn);
1504
1505 return ret ?: nbytes;
1506 }
1507
resctrl_mbm_assign_mode_show(struct kernfs_open_file * of,struct seq_file * s,void * v)1508 int resctrl_mbm_assign_mode_show(struct kernfs_open_file *of,
1509 struct seq_file *s, void *v)
1510 {
1511 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1512 bool enabled;
1513
1514 if (!info_kn_lock(of->kn))
1515 return -ENOENT;
1516 enabled = resctrl_arch_mbm_cntr_assign_enabled(r);
1517
1518 if (r->mon.mbm_cntr_assignable) {
1519 if (enabled)
1520 seq_puts(s, "[mbm_event]\n");
1521 else
1522 seq_puts(s, "[default]\n");
1523
1524 if (!r->mon.mbm_cntr_assign_fixed) {
1525 if (enabled)
1526 seq_puts(s, "default\n");
1527 else
1528 seq_puts(s, "mbm_event\n");
1529 }
1530 } else {
1531 seq_puts(s, "[default]\n");
1532 }
1533
1534 info_kn_unlock(of->kn);
1535
1536 return 0;
1537 }
1538
resctrl_mbm_assign_mode_write(struct kernfs_open_file * of,char * buf,size_t nbytes,loff_t off)1539 ssize_t resctrl_mbm_assign_mode_write(struct kernfs_open_file *of, char *buf,
1540 size_t nbytes, loff_t off)
1541 {
1542 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1543 struct rdt_l3_mon_domain *d;
1544 int ret = 0;
1545 bool enable;
1546
1547 if (!info_kn_lock(of->kn))
1548 return -ENOENT;
1549
1550 rdt_last_cmd_clear();
1551
1552 /* Valid input requires a trailing newline */
1553 if (nbytes == 0 || buf[nbytes - 1] != '\n') {
1554 rdt_last_cmd_puts("mbm_assign_mode: Invalid input\n");
1555 ret = -EINVAL;
1556 goto out_unlock;
1557 }
1558
1559 buf[nbytes - 1] = '\0';
1560
1561 if (!strcmp(buf, "default")) {
1562 enable = 0;
1563 } else if (!strcmp(buf, "mbm_event")) {
1564 if (r->mon.mbm_cntr_assignable) {
1565 enable = 1;
1566 } else {
1567 ret = -EINVAL;
1568 rdt_last_cmd_puts("mbm_event mode is not supported\n");
1569 goto out_unlock;
1570 }
1571 } else {
1572 ret = -EINVAL;
1573 rdt_last_cmd_puts("Unsupported assign mode\n");
1574 goto out_unlock;
1575 }
1576
1577 if (enable != resctrl_arch_mbm_cntr_assign_enabled(r)) {
1578 if (r->mon.mbm_cntr_assign_fixed) {
1579 ret = -EINVAL;
1580 rdt_last_cmd_puts("Counter assignment mode is not configurable\n");
1581 goto out_unlock;
1582 }
1583
1584 ret = resctrl_arch_mbm_cntr_assign_set(r, enable);
1585 if (ret)
1586 goto out_unlock;
1587
1588 /* Update the visibility of BMEC related files */
1589 resctrl_bmec_files_show(r, NULL, !enable);
1590
1591 /*
1592 * Initialize the default memory transaction values for
1593 * total and local events.
1594 */
1595 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
1596 mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask;
1597 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
1598 mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask &
1599 (READS_TO_LOCAL_MEM |
1600 READS_TO_LOCAL_S_MEM |
1601 NON_TEMP_WRITE_TO_LOCAL_MEM);
1602 /* Enable auto assignment when switching to "mbm_event" mode */
1603 if (enable)
1604 r->mon.mbm_assign_on_mkdir = true;
1605 /*
1606 * Reset all the non-achitectural RMID state and assignable counters.
1607 */
1608 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1609 mbm_cntr_free_all(r, d);
1610 resctrl_reset_rmid_all(r, d);
1611 }
1612 }
1613
1614 out_unlock:
1615 info_kn_unlock(of->kn);
1616
1617 return ret ?: nbytes;
1618 }
1619
resctrl_num_mbm_cntrs_show(struct kernfs_open_file * of,struct seq_file * s,void * v)1620 int resctrl_num_mbm_cntrs_show(struct kernfs_open_file *of,
1621 struct seq_file *s, void *v)
1622 {
1623 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1624 struct rdt_l3_mon_domain *dom;
1625 bool sep = false;
1626
1627 if (!info_kn_lock(of->kn))
1628 return -ENOENT;
1629
1630 list_for_each_entry_rcu(dom, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1631 if (sep)
1632 seq_putc(s, ';');
1633
1634 seq_printf(s, "%d=%d", dom->hdr.id, r->mon.num_mbm_cntrs);
1635 sep = true;
1636 }
1637 seq_putc(s, '\n');
1638
1639 info_kn_unlock(of->kn);
1640 return 0;
1641 }
1642
resctrl_available_mbm_cntrs_show(struct kernfs_open_file * of,struct seq_file * s,void * v)1643 int resctrl_available_mbm_cntrs_show(struct kernfs_open_file *of,
1644 struct seq_file *s, void *v)
1645 {
1646 struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
1647 struct rdt_l3_mon_domain *dom;
1648 bool sep = false;
1649 u32 cntrs, i;
1650 int ret = 0;
1651
1652 if (!info_kn_lock(of->kn))
1653 return -ENOENT;
1654
1655 rdt_last_cmd_clear();
1656
1657 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1658 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1659 ret = -EINVAL;
1660 goto out_unlock;
1661 }
1662
1663 list_for_each_entry_rcu(dom, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1664 if (sep)
1665 seq_putc(s, ';');
1666
1667 cntrs = 0;
1668 for (i = 0; i < r->mon.num_mbm_cntrs; i++) {
1669 if (!dom->cntr_cfg[i].rdtgrp)
1670 cntrs++;
1671 }
1672
1673 seq_printf(s, "%d=%u", dom->hdr.id, cntrs);
1674 sep = true;
1675 }
1676 seq_putc(s, '\n');
1677
1678 out_unlock:
1679 info_kn_unlock(of->kn);
1680
1681 return ret;
1682 }
1683
mbm_L3_assignments_show(struct kernfs_open_file * of,struct seq_file * s,void * v)1684 int mbm_L3_assignments_show(struct kernfs_open_file *of, struct seq_file *s, void *v)
1685 {
1686 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1687 struct rdt_l3_mon_domain *d;
1688 struct rdtgroup *rdtgrp;
1689 struct mon_evt *mevt;
1690 int ret = 0;
1691 bool sep;
1692
1693 rdtgrp = rdtgroup_kn_lock_live(of->kn);
1694 if (!rdtgrp) {
1695 ret = -ENOENT;
1696 goto out_unlock;
1697 }
1698
1699 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1700 rdt_last_cmd_puts("mbm_event counter assignment mode is not enabled\n");
1701 ret = -EINVAL;
1702 goto out_unlock;
1703 }
1704
1705 for_each_mon_event(mevt) {
1706 if (mevt->rid != r->rid || !mevt->enabled || !resctrl_is_mbm_event(mevt->evtid))
1707 continue;
1708
1709 sep = false;
1710 seq_printf(s, "%s:", mevt->name);
1711 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1712 if (sep)
1713 seq_putc(s, ';');
1714
1715 if (mbm_cntr_get(r, d, rdtgrp, mevt->evtid) < 0)
1716 seq_printf(s, "%d=_", d->hdr.id);
1717 else
1718 seq_printf(s, "%d=e", d->hdr.id);
1719
1720 sep = true;
1721 }
1722 seq_putc(s, '\n');
1723 }
1724
1725 out_unlock:
1726 rdtgroup_kn_unlock(of->kn);
1727
1728 return ret;
1729 }
1730
1731 /*
1732 * mbm_get_mon_event_by_name() - Return the mon_evt entry for the matching
1733 * event name.
1734 */
mbm_get_mon_event_by_name(struct rdt_resource * r,char * name)1735 static struct mon_evt *mbm_get_mon_event_by_name(struct rdt_resource *r, char *name)
1736 {
1737 struct mon_evt *mevt;
1738
1739 for_each_mon_event(mevt) {
1740 if (mevt->rid == r->rid && mevt->enabled &&
1741 resctrl_is_mbm_event(mevt->evtid) &&
1742 !strcmp(mevt->name, name))
1743 return mevt;
1744 }
1745
1746 return NULL;
1747 }
1748
rdtgroup_modify_assign_state(char * assign,struct rdt_l3_mon_domain * d,struct rdtgroup * rdtgrp,struct mon_evt * mevt)1749 static int rdtgroup_modify_assign_state(char *assign, struct rdt_l3_mon_domain *d,
1750 struct rdtgroup *rdtgrp, struct mon_evt *mevt)
1751 {
1752 int ret = 0;
1753
1754 if (!assign || strlen(assign) != 1)
1755 return -EINVAL;
1756
1757 switch (*assign) {
1758 case 'e':
1759 ret = rdtgroup_assign_cntr_event(d, rdtgrp, mevt);
1760 break;
1761 case '_':
1762 rdtgroup_unassign_cntr_event(d, rdtgrp, mevt);
1763 break;
1764 default:
1765 ret = -EINVAL;
1766 break;
1767 }
1768
1769 return ret;
1770 }
1771
resctrl_parse_mbm_assignment(struct rdt_resource * r,struct rdtgroup * rdtgrp,char * event,char * tok)1772 static int resctrl_parse_mbm_assignment(struct rdt_resource *r, struct rdtgroup *rdtgrp,
1773 char *event, char *tok)
1774 {
1775 struct rdt_l3_mon_domain *d;
1776 unsigned long dom_id = 0;
1777 char *dom_str, *id_str;
1778 struct mon_evt *mevt;
1779 int ret;
1780
1781 mevt = mbm_get_mon_event_by_name(r, event);
1782 if (!mevt) {
1783 rdt_last_cmd_printf("Invalid event %s\n", event);
1784 return -ENOENT;
1785 }
1786
1787 next:
1788 if (!tok || tok[0] == '\0')
1789 return 0;
1790
1791 /* Start processing the strings for each domain */
1792 dom_str = strim(strsep(&tok, ";"));
1793
1794 id_str = strsep(&dom_str, "=");
1795
1796 /* Check for domain id '*' which means all domains */
1797 if (id_str && *id_str == '*') {
1798 ret = rdtgroup_modify_assign_state(dom_str, NULL, rdtgrp, mevt);
1799 if (ret)
1800 rdt_last_cmd_printf("Assign operation '%s:*=%s' failed\n",
1801 event, dom_str);
1802 return ret;
1803 } else if (!id_str || kstrtoul(id_str, 10, &dom_id)) {
1804 rdt_last_cmd_puts("Missing domain id\n");
1805 return -EINVAL;
1806 }
1807
1808 /* Verify if the dom_id is valid */
1809 list_for_each_entry_rcu(d, &r->mon_domains, hdr.list, lockdep_is_cpus_held()) {
1810 if (d->hdr.id == dom_id) {
1811 ret = rdtgroup_modify_assign_state(dom_str, d, rdtgrp, mevt);
1812 if (ret) {
1813 rdt_last_cmd_printf("Assign operation '%s:%ld=%s' failed\n",
1814 event, dom_id, dom_str);
1815 return ret;
1816 }
1817 goto next;
1818 }
1819 }
1820
1821 rdt_last_cmd_printf("Invalid domain id %ld\n", dom_id);
1822 return -EINVAL;
1823 }
1824
mbm_L3_assignments_write(struct kernfs_open_file * of,char * buf,size_t nbytes,loff_t off)1825 ssize_t mbm_L3_assignments_write(struct kernfs_open_file *of, char *buf,
1826 size_t nbytes, loff_t off)
1827 {
1828 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1829 struct rdtgroup *rdtgrp;
1830 char *token, *event;
1831 int ret = 0;
1832
1833 rdtgrp = rdtgroup_kn_lock_live(of->kn);
1834 if (!rdtgrp) {
1835 rdtgroup_kn_unlock(of->kn);
1836 return -ENOENT;
1837 }
1838
1839 /* Valid input requires a trailing newline */
1840 if (nbytes == 0 || buf[nbytes - 1] != '\n') {
1841 rdt_last_cmd_puts("mbm_L3_assignments: Invalid input\n");
1842 ret = -EINVAL;
1843 goto out_unlock;
1844 }
1845
1846 buf[nbytes - 1] = '\0';
1847
1848 if (!resctrl_arch_mbm_cntr_assign_enabled(r)) {
1849 rdt_last_cmd_puts("mbm_event mode is not enabled\n");
1850 ret = -EINVAL;
1851 goto out_unlock;
1852 }
1853
1854 while ((token = strsep(&buf, "\n")) != NULL) {
1855 /*
1856 * The write command follows the following format:
1857 * "<Event>:<Domain ID>=<Assignment state>"
1858 * Extract the event name first.
1859 */
1860 event = strsep(&token, ":");
1861
1862 ret = resctrl_parse_mbm_assignment(r, rdtgrp, event, token);
1863 if (ret)
1864 break;
1865 }
1866
1867 out_unlock:
1868 rdtgroup_kn_unlock(of->kn);
1869
1870 return ret ?: nbytes;
1871 }
1872
closid_num_dirty_rmid_alloc(struct rdt_resource * r)1873 static int closid_num_dirty_rmid_alloc(struct rdt_resource *r)
1874 {
1875 if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
1876 u32 num_closid = resctrl_arch_get_num_closid(r);
1877 u32 *tmp;
1878
1879 /* For ARM memory ordering access to closid_num_dirty_rmid */
1880 mutex_lock(&rdtgroup_mutex);
1881
1882 /*
1883 * If the architecture hasn't provided a sanitised value here,
1884 * this may result in larger arrays than necessary. Resctrl will
1885 * use a smaller system wide value based on the resources in
1886 * use.
1887 */
1888 tmp = kcalloc(num_closid, sizeof(*tmp), GFP_KERNEL);
1889 if (!tmp) {
1890 mutex_unlock(&rdtgroup_mutex);
1891 return -ENOMEM;
1892 }
1893
1894 closid_num_dirty_rmid = tmp;
1895
1896 mutex_unlock(&rdtgroup_mutex);
1897 }
1898
1899 return 0;
1900 }
1901
closid_num_dirty_rmid_free(void)1902 static void closid_num_dirty_rmid_free(void)
1903 {
1904 if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
1905 mutex_lock(&rdtgroup_mutex);
1906 kfree(closid_num_dirty_rmid);
1907 closid_num_dirty_rmid = NULL;
1908 mutex_unlock(&rdtgroup_mutex);
1909 }
1910 }
1911
1912 /**
1913 * resctrl_l3_mon_resource_init() - Initialise global monitoring structures.
1914 *
1915 * Allocate and initialise global monitor resources that do not belong to a
1916 * specific domain. i.e. the closid_num_dirty_rmid[] used to find the CLOSID
1917 * with the cleanest set of RMIDs.
1918 * Called once during boot after the struct rdt_resource's have been configured
1919 * but before the filesystem is mounted.
1920 * Resctrl's cpuhp callbacks may be called before this point to bring a domain
1921 * online.
1922 *
1923 * Return: 0 for success, or -ENOMEM.
1924 */
resctrl_l3_mon_resource_init(void)1925 int resctrl_l3_mon_resource_init(void)
1926 {
1927 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1928 int ret;
1929
1930 if (!r->mon_capable)
1931 return 0;
1932
1933 ret = closid_num_dirty_rmid_alloc(r);
1934 if (ret)
1935 return ret;
1936
1937 if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) {
1938 mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].configurable = true;
1939 resctrl_file_fflags_init("mbm_total_bytes_config",
1940 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
1941 }
1942 if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID)) {
1943 mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].configurable = true;
1944 resctrl_file_fflags_init("mbm_local_bytes_config",
1945 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
1946 }
1947
1948 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
1949 mba_mbps_default_event = QOS_L3_MBM_LOCAL_EVENT_ID;
1950 else if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
1951 mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID;
1952
1953 if (r->mon.mbm_cntr_assignable) {
1954 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_TOTAL_EVENT_ID))
1955 mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask;
1956 if (resctrl_is_mon_event_enabled(QOS_L3_MBM_LOCAL_EVENT_ID))
1957 mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].evt_cfg = r->mon.mbm_cfg_mask &
1958 (READS_TO_LOCAL_MEM |
1959 READS_TO_LOCAL_S_MEM |
1960 NON_TEMP_WRITE_TO_LOCAL_MEM);
1961 r->mon.mbm_assign_on_mkdir = true;
1962 resctrl_file_fflags_init("num_mbm_cntrs",
1963 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
1964 resctrl_file_fflags_init("available_mbm_cntrs",
1965 RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
1966 resctrl_file_fflags_init("event_filter", RFTYPE_ASSIGN_CONFIG);
1967 if (r->mon.mbm_cntr_configurable)
1968 resctrl_file_mode_init("event_filter", 0644);
1969 resctrl_file_fflags_init("mbm_assign_on_mkdir", RFTYPE_MON_INFO |
1970 RFTYPE_RES_CACHE);
1971 resctrl_file_fflags_init("mbm_L3_assignments", RFTYPE_MON_BASE);
1972 }
1973
1974 return 0;
1975 }
1976
resctrl_l3_mon_resource_exit(void)1977 void resctrl_l3_mon_resource_exit(void)
1978 {
1979 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
1980
1981 if (!r->mon_capable)
1982 return;
1983
1984 closid_num_dirty_rmid_free();
1985 }
1986