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: Call resctrl_init() on platforms that can support resctrl

Now that MPAM links against resctrl, call resctrl_init() to register the
filesystem and setup resctrl's structures.

Tested-by: Gavin Shan <gshan@redhat.com>
Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: Peter Newman <peternewman@google.com>
Tested-by: Zeng Heng <zengheng4@huawei.com>
Tested-by: Punit Agrawal <punit.agrawal@oss.qualcomm.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: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>

+94 -5
+28 -4
drivers/resctrl/mpam_devices.c
··· 74 74 static char *mpam_disable_reason; 75 75 76 76 /* 77 + * Whether resctrl has been setup. Used by cpuhp in preference to 78 + * mpam_is_enabled(). The disable call after an error interrupt makes 79 + * mpam_is_enabled() false before the cpuhp callbacks are made. 80 + * Reads/writes should hold mpam_cpuhp_state_lock, (or be cpuhp callbacks). 81 + */ 82 + static bool mpam_resctrl_enabled; 83 + 84 + /* 77 85 * An MSC is a physical container for controls and monitors, each identified by 78 86 * their RIS index. These share a base-address, interrupts and some MMIO 79 87 * registers. A vMSC is a virtual container for RIS in an MSC that control or ··· 1627 1619 mpam_reprogram_msc(msc); 1628 1620 } 1629 1621 1630 - if (mpam_is_enabled()) 1622 + if (mpam_resctrl_enabled) 1631 1623 return mpam_resctrl_online_cpu(cpu); 1632 1624 1633 1625 return 0; ··· 1673 1665 { 1674 1666 struct mpam_msc *msc; 1675 1667 1676 - if (mpam_is_enabled()) 1668 + if (mpam_resctrl_enabled) 1677 1669 mpam_resctrl_offline_cpu(cpu); 1678 1670 1679 1671 guard(srcu)(&mpam_srcu); ··· 2534 2526 } 2535 2527 2536 2528 static_branch_enable(&mpam_enabled); 2529 + mpam_resctrl_enabled = true; 2537 2530 mpam_register_cpuhp_callbacks(mpam_cpu_online, mpam_cpu_offline, 2538 2531 "mpam:online"); 2539 2532 ··· 2594 2585 void mpam_disable(struct work_struct *ignored) 2595 2586 { 2596 2587 int idx; 2588 + bool do_resctrl_exit; 2597 2589 struct mpam_class *class; 2598 2590 struct mpam_msc *msc, *tmp; 2591 + 2592 + if (mpam_is_enabled()) 2593 + static_branch_disable(&mpam_enabled); 2599 2594 2600 2595 mutex_lock(&mpam_cpuhp_state_lock); 2601 2596 if (mpam_cpuhp_state) { 2602 2597 cpuhp_remove_state(mpam_cpuhp_state); 2603 2598 mpam_cpuhp_state = 0; 2604 2599 } 2600 + 2601 + /* 2602 + * Removing the cpuhp state called mpam_cpu_offline() and told resctrl 2603 + * all the CPUs are offline. 2604 + */ 2605 + do_resctrl_exit = mpam_resctrl_enabled; 2606 + mpam_resctrl_enabled = false; 2605 2607 mutex_unlock(&mpam_cpuhp_state_lock); 2606 2608 2607 - static_branch_disable(&mpam_enabled); 2609 + if (do_resctrl_exit) 2610 + mpam_resctrl_exit(); 2608 2611 2609 2612 mpam_unregister_irqs(); 2610 2613 2611 2614 idx = srcu_read_lock(&mpam_srcu); 2612 2615 list_for_each_entry_srcu(class, &mpam_classes, classes_list, 2613 - srcu_read_lock_held(&mpam_srcu)) 2616 + srcu_read_lock_held(&mpam_srcu)) { 2614 2617 mpam_reset_class(class); 2618 + if (do_resctrl_exit) 2619 + mpam_resctrl_teardown_class(class); 2620 + } 2615 2621 srcu_read_unlock(&mpam_srcu, idx); 2616 2622 2617 2623 mutex_lock(&mpam_list_lock);
+4
drivers/resctrl/mpam_internal.h
··· 431 431 432 432 #ifdef CONFIG_RESCTRL_FS 433 433 int mpam_resctrl_setup(void); 434 + void mpam_resctrl_exit(void); 434 435 int mpam_resctrl_online_cpu(unsigned int cpu); 435 436 void mpam_resctrl_offline_cpu(unsigned int cpu); 437 + void mpam_resctrl_teardown_class(struct mpam_class *class); 436 438 #else 437 439 static inline int mpam_resctrl_setup(void) { return 0; } 440 + static inline void mpam_resctrl_exit(void) { } 438 441 static inline int mpam_resctrl_online_cpu(unsigned int cpu) { return 0; } 439 442 static inline void mpam_resctrl_offline_cpu(unsigned int cpu) { } 443 + static inline void mpam_resctrl_teardown_class(struct mpam_class *class) { } 440 444 #endif /* CONFIG_RESCTRL_FS */ 441 445 442 446 /*
+62 -1
drivers/resctrl/mpam_resctrl.c
··· 69 69 static bool cacheinfo_ready; 70 70 static DECLARE_WAIT_QUEUE_HEAD(wait_cacheinfo_ready); 71 71 72 + /* 73 + * If resctrl_init() succeeded, resctrl_exit() can be used to remove support 74 + * for the filesystem in the event of an error. 75 + */ 76 + static bool resctrl_enabled; 77 + 72 78 bool resctrl_arch_alloc_capable(void) 73 79 { 74 80 struct mpam_resctrl_res *res; ··· 366 360 { 367 361 struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[evtid]; 368 362 363 + if (!mpam_is_enabled()) 364 + return -EINVAL; 365 + 369 366 if (!mon->class) 370 367 return -EINVAL; 371 368 ··· 410 401 u32 mon_idx) 411 402 { 412 403 struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[evtid]; 404 + 405 + if (!mpam_is_enabled()) 406 + return; 413 407 414 408 if (!mon->class) 415 409 return; ··· 499 487 struct mpam_resctrl_mon *mon = &mpam_resctrl_counters[eventid]; 500 488 501 489 resctrl_arch_rmid_read_context_check(); 490 + 491 + if (!mpam_is_enabled()) 492 + return -EINVAL; 502 493 503 494 if (eventid >= QOS_NUM_EVENTS || !mon->class) 504 495 return -EINVAL; ··· 1177 1162 lockdep_assert_cpus_held(); 1178 1163 lockdep_assert_irqs_enabled(); 1179 1164 1165 + if (!mpam_is_enabled()) 1166 + return -EINVAL; 1167 + 1180 1168 /* 1181 1169 * No need to check the CPU as mpam_apply_config() doesn't care, and 1182 1170 * resctrl_arch_update_domains() relies on this. ··· 1244 1226 1245 1227 lockdep_assert_cpus_held(); 1246 1228 lockdep_assert_irqs_enabled(); 1229 + 1230 + if (!mpam_is_enabled()) 1231 + return -EINVAL; 1247 1232 1248 1233 list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list) { 1249 1234 for (enum resctrl_conf_type t = 0; t < CDP_NUM_TYPES; t++) { ··· 1640 1619 return -EOPNOTSUPP; 1641 1620 } 1642 1621 1643 - /* TODO: call resctrl_init() */ 1622 + err = resctrl_init(); 1623 + if (err) 1624 + return err; 1625 + 1626 + WRITE_ONCE(resctrl_enabled, true); 1644 1627 1645 1628 return 0; 1646 1629 ··· 1652 1627 cpus_read_unlock(); 1653 1628 pr_debug("Internal error %d - resctrl not supported\n", err); 1654 1629 return err; 1630 + } 1631 + 1632 + void mpam_resctrl_exit(void) 1633 + { 1634 + if (!READ_ONCE(resctrl_enabled)) 1635 + return; 1636 + 1637 + WRITE_ONCE(resctrl_enabled, false); 1638 + resctrl_exit(); 1639 + } 1640 + 1641 + /* 1642 + * The driver is detaching an MSC from this class, if resctrl was using it, 1643 + * pull on resctrl_exit(). 1644 + */ 1645 + void mpam_resctrl_teardown_class(struct mpam_class *class) 1646 + { 1647 + struct mpam_resctrl_res *res; 1648 + enum resctrl_res_level rid; 1649 + struct mpam_resctrl_mon *mon; 1650 + enum resctrl_event_id eventid; 1651 + 1652 + might_sleep(); 1653 + 1654 + for_each_mpam_resctrl_control(res, rid) { 1655 + if (res->class == class) { 1656 + res->class = NULL; 1657 + break; 1658 + } 1659 + } 1660 + for_each_mpam_resctrl_mon(mon, eventid) { 1661 + if (mon->class == class) { 1662 + mon->class = NULL; 1663 + break; 1664 + } 1665 + } 1655 1666 } 1656 1667 1657 1668 static int __init __cacheinfo_ready(void)