x86/resctrl: Check all domains are offline in resctrl_exit()

resctrl_exit() removes things like the resctrl mount point directory
and unregisters the filesystem prior to freeing data structures that
were allocated during resctrl_init().

This assumes that there are no online domains when resctrl_exit() is
called. If any domain were online, the limbo or overflow handler could
be scheduled to run.

Add a check for any online control or monitor domains, and document that
the architecture code is required to offline all monitor and control
domains before calling resctrl_exit().

Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: James Morse <james.morse@arm.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Reviewed-by: Fenghua Yu <fenghuay@nvidia.com>
Tested-by: Fenghua Yu <fenghuay@nvidia.com>
Tested-by: Babu Moger <babu.moger@amd.com>
Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
Tested-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/20250515165855.31452-8-james.morse@arm.com
This commit is contained in:
James Morse 2025-05-15 16:58:37 +00:00 committed by Borislav Petkov (AMD)
parent 7704fb81bc
commit 8eb7ad66ba

View File

@ -4420,8 +4420,41 @@ int __init resctrl_init(void)
return ret;
}
static bool __exit resctrl_online_domains_exist(void)
{
struct rdt_resource *r;
/*
* Only walk capable resources to allow resctrl_arch_get_resource()
* to return dummy 'not capable' resources.
*/
for_each_alloc_capable_rdt_resource(r) {
if (!list_empty(&r->ctrl_domains))
return true;
}
for_each_mon_capable_rdt_resource(r) {
if (!list_empty(&r->mon_domains))
return true;
}
return false;
}
/*
* resctrl_exit() - Remove the resctrl filesystem and free resources.
*
* When called by the architecture code, all CPUs and resctrl domains must be
* offline. This ensures the limbo and overflow handlers are not scheduled to
* run, meaning the data structures they access can be freed by
* resctrl_mon_resource_exit().
*/
void __exit resctrl_exit(void)
{
cpus_read_lock();
WARN_ON_ONCE(resctrl_online_domains_exist());
cpus_read_unlock();
debugfs_remove_recursive(debugfs_resctrl);
unregister_filesystem(&rdt_fs_type);
sysfs_remove_mount_point(fs_kobj, "resctrl");