diff --git a/fs/resctrl/internal.h b/fs/resctrl/internal.h index 839fbcf51ed2b447c882b3e7dc1b7c59f9a1433f..0e8865bf012a1461de8dfed8ea3deac41fb17271 100644 --- a/fs/resctrl/internal.h +++ b/fs/resctrl/internal.h @@ -294,5 +294,6 @@ bool has_busy_rmid(struct rdt_domain *d); void __check_limbo(struct rdt_domain *d, bool force_free); void rdt_staged_configs_clear(void); int resctrl_find_cleanest_closid(void); +struct rmid_entry *resctrl_find_free_rmid(u32 closid); #endif /* _FS_RESCTRL_INTERNAL_H */ diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index d104970136383523252629381d5bbc3f17317078..b651b37e7e6571a92e8cc7117fb2fb3675a79dd9 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -178,7 +178,7 @@ bool has_busy_rmid(struct rdt_domain *d) return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit; } -static struct rmid_entry *resctrl_find_free_rmid(u32 closid) +struct rmid_entry *resctrl_find_free_rmid(u32 closid) { struct rmid_entry *itr; u32 itr_idx, cmp_idx; diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index 4e0b2dfaa436733321fa1f3be1dc8a0c7b448a9e..96a9c3d001dbe5eaefaa7c934018d971a3171595 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -3813,6 +3813,8 @@ static void mongrp_reparent(struct rdtgroup *rdtgrp, list_move_tail(&rdtgrp->mon.crdtgrp_list, &new_prdtgrp->mon.crdtgrp_list); + free_rmid(rdtgrp->closid, rdtgrp->mon.rmid); + rdtgrp->mon.rmid = alloc_rmid(new_prdtgrp->closid); rdtgrp->mon.parent = new_prdtgrp; rdtgrp->closid = new_prdtgrp->closid; @@ -3826,6 +3828,7 @@ static int rdtgroup_rename(struct kernfs_node *kn, struct kernfs_node *new_parent, const char *new_name) { struct rdtgroup *new_prdtgrp; + struct rmid_entry *entry; struct rdtgroup *rdtgrp; cpumask_var_t tmpmask; int ret; @@ -3884,6 +3887,20 @@ static int rdtgroup_rename(struct kernfs_node *kn, goto out; } + /* + * Unlike RDT, the rmid and closid in MPAM have a hierarchical + * relationship. Therefore, first check whether there are still + * free rmids available under the target closid. + */ + if (IS_ENABLED(CONFIG_ARM64_MPAM)) { + entry = resctrl_find_free_rmid(new_prdtgrp->closid); + if (IS_ERR(entry)) { + rdt_last_cmd_puts("Destination has been out of RMIDs\n"); + ret = PTR_ERR(entry); + goto out; + } + } + /* * Allocate the cpumask for use in mongrp_reparent() to avoid the * possibility of failing to allocate it after kernfs_rename() has