[PATCH v3 8/9] fs/resctrl: Wire up rmid expansion and reclaim functions

Zeng Heng posted 9 patches 2 weeks, 6 days ago
[PATCH v3 8/9] fs/resctrl: Wire up rmid expansion and reclaim functions
Posted by Zeng Heng 2 weeks, 6 days ago
The previous patch implemented resctrl_arch_rmid_expand() and
resctrl_arch_rmid_reclaim() for ARM MPAM. This patch integrates
these architecture-specific functions into the generic resctrl layer.

Refactor resctrl_find_free_rmid() to support dynamic rmid expansion.
If no free rmid is available for the current closid, attempt to expand
via resctrl_arch_expand_rmid(). On success, retry the rmid allocation.

As this capability is architecture-specific, x86 maintains existing
behavior by returning -ENOSPC when rmid resources are exhausted.

Additionally, invoke resctrl_arch_rmid_reclaim() when rmids are released
to enable architecture-specific resource cleanup.

Signed-off-by: Zeng Heng <zengheng4@huawei.com>
---
 arch/x86/include/asm/resctrl.h |  7 +++++++
 fs/resctrl/monitor.c           | 32 ++++++++++++++++++++++++++++++--
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 575f8408a9e7..7f8c8d84f2a0 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -167,6 +167,13 @@ static inline void resctrl_arch_sched_in(struct task_struct *tsk)
 		__resctrl_sched_in(tsk);
 }
 
+static inline int resctrl_arch_rmid_expand(u32 closid)
+{
+	return -ENOSPC;
+}
+
+static inline void resctrl_arch_rmid_reclaim(u32 closid, u32 rmid) {}
+
 static inline void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
 {
 	*rmid = idx;
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 4e78fb194c16..c58440eb7cc9 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -122,6 +122,8 @@ static void limbo_release_entry(struct rmid_entry *entry)
 
 	if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
 		closid_num_dirty_rmid[entry->closid]--;
+
+	resctrl_arch_rmid_reclaim(entry->closid, entry->rmid);
 }
 
 /*
@@ -197,7 +199,7 @@ bool has_busy_rmid(struct rdt_l3_mon_domain *d)
 	return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
 }
 
-static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
+static struct rmid_entry *__resctrl_find_free_rmid(u32 closid)
 {
 	struct rmid_entry *itr;
 	u32 itr_idx, cmp_idx;
@@ -214,7 +216,12 @@ static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
 		 * very first entry will be returned.
 		 */
 		itr_idx = resctrl_arch_rmid_idx_encode(itr->closid, itr->rmid);
+		if (itr_idx == U32_MAX)
+			continue;
+
 		cmp_idx = resctrl_arch_rmid_idx_encode(closid, itr->rmid);
+		if (cmp_idx == U32_MAX)
+			continue;
 
 		if (itr_idx == cmp_idx)
 			return itr;
@@ -223,6 +230,25 @@ static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
 	return ERR_PTR(-ENOSPC);
 }
 
+static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
+{
+	struct rmid_entry *err;
+	int ret;
+
+	err = __resctrl_find_free_rmid(closid);
+	if (err == ERR_PTR(-ENOSPC)) {
+		ret = resctrl_arch_rmid_expand(closid);
+		if (ret < 0)
+			/* Out of rmid */
+			goto out;
+
+		/* Try it again */
+		return __resctrl_find_free_rmid(closid);
+	}
+out:
+	return err;
+}
+
 /**
  * resctrl_find_cleanest_closid() - Find a CLOSID where all the associated
  *                                  RMID are clean, or the CLOSID that has
@@ -340,8 +366,10 @@ void free_rmid(u32 closid, u32 rmid)
 
 	if (resctrl_is_mon_event_enabled(QOS_L3_OCCUP_EVENT_ID))
 		add_rmid_to_limbo(entry);
-	else
+	else {
 		list_add_tail(&entry->list, &rmid_free_lru);
+		resctrl_arch_rmid_reclaim(closid, rmid);
+	}
 }
 
 bool rmid_is_occupied(u32 closid, u32 rmid)
-- 
2.25.1