Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

arm_mpam: resctrl: Add support for csu counters

resctrl exposes a counter via a file named llc_occupancy. This isn't really
a counter as its value goes up and down, this is a snapshot of the cache
storage usage monitor.

Add some picking code which will only find an L3. The resctrl counter
file is called llc_occupancy but we don't check it is the last one as
it is already identified as L3.

Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: Zeng Heng <zengheng4@huawei.com>
Tested-by: Punit Agrawal <punit.agrawal@oss.qualcomm.com>
Tested-by: Gavin Shan <gshan@redhat.com>
Tested-by: Jesse Chick <jessechick@os.amperecomputing.com>
Reviewed-by: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Gavin Shan <gshan@redhat.com>
Co-developed-by: Dave Martin <dave.martin@arm.com>
Signed-off-by: Dave Martin <dave.martin@arm.com>
Co-developed-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>

+83
+83
drivers/resctrl/mpam_resctrl.c
··· 311 311 return mba_class_use_mbw_max(cprops); 312 312 } 313 313 314 + static bool cache_has_usable_csu(struct mpam_class *class) 315 + { 316 + struct mpam_props *cprops; 317 + 318 + if (!class) 319 + return false; 320 + 321 + cprops = &class->props; 322 + 323 + if (!mpam_has_feature(mpam_feat_msmon_csu, cprops)) 324 + return false; 325 + 326 + /* 327 + * CSU counters settle on the value, so we can get away with 328 + * having only one. 329 + */ 330 + if (!cprops->num_csu_mon) 331 + return false; 332 + 333 + return true; 334 + } 335 + 314 336 /* 315 337 * Calculate the worst-case percentage change from each implemented step 316 338 * in the control. ··· 649 627 candidate_class->level); 650 628 res = &mpam_resctrl_controls[RDT_RESOURCE_MBA]; 651 629 res->class = candidate_class; 630 + } 631 + } 632 + 633 + static void counter_update_class(enum resctrl_event_id evt_id, 634 + struct mpam_class *class) 635 + { 636 + struct mpam_class *existing_class = mpam_resctrl_counters[evt_id].class; 637 + 638 + if (existing_class) { 639 + if (class->level == 3) { 640 + pr_debug("Existing class is L3 - L3 wins\n"); 641 + return; 642 + } 643 + 644 + if (existing_class->level < class->level) { 645 + pr_debug("Existing class is closer to L3, %u versus %u - closer is better\n", 646 + existing_class->level, class->level); 647 + return; 648 + } 649 + } 650 + 651 + mpam_resctrl_counters[evt_id].class = class; 652 + } 653 + 654 + static void mpam_resctrl_pick_counters(void) 655 + { 656 + struct mpam_class *class; 657 + 658 + lockdep_assert_cpus_held(); 659 + 660 + guard(srcu)(&mpam_srcu); 661 + list_for_each_entry_srcu(class, &mpam_classes, classes_list, 662 + srcu_read_lock_held(&mpam_srcu)) { 663 + /* The name of the resource is L3... */ 664 + if (class->type == MPAM_CLASS_CACHE && class->level != 3) { 665 + pr_debug("class %u is a cache but not the L3", class->level); 666 + continue; 667 + } 668 + 669 + if (!cpumask_equal(&class->affinity, cpu_possible_mask)) { 670 + pr_debug("class %u does not cover all CPUs", 671 + class->level); 672 + continue; 673 + } 674 + 675 + if (cache_has_usable_csu(class)) { 676 + pr_debug("class %u has usable CSU", 677 + class->level); 678 + 679 + /* CSU counters only make sense on a cache. */ 680 + switch (class->type) { 681 + case MPAM_CLASS_CACHE: 682 + counter_update_class(QOS_L3_OCCUP_EVENT_ID, class); 683 + break; 684 + default: 685 + break; 686 + } 687 + } 652 688 } 653 689 } 654 690 ··· 1343 1263 goto internal_error; 1344 1264 } 1345 1265 } 1266 + 1267 + /* Find some classes to use for monitors */ 1268 + mpam_resctrl_pick_counters(); 1346 1269 1347 1270 for_each_mpam_resctrl_mon(mon, eventid) { 1348 1271 if (!mon->class)