From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from canpmsgout01.his.huawei.com (canpmsgout01.his.huawei.com [113.46.200.216]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B14C13ACA65 for ; Mon, 13 Apr 2026 08:54:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.216 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776070463; cv=none; b=MO9qSO62gl2xxmtkGjSMGI/6temN5Gy1rDjCt4CeKbBnGCUYeL7AL7h774P2GpEddEBDELiYfcHJ7bcQTvrit1gPxYQPeZYUdwAv8MA1ro3DqSzYqMCVh4rnItjY5u8UZVbk2TOXBWCy6oSxhLRo7355jhKj5Mep2krLiBb5Dbc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776070463; c=relaxed/simple; bh=UEpF6RyuybriBOZtKqW4IPSejTORNNutnXY8onidzMs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VQ2G/V0RcQ4mbHh4Sd0whoF6YIjE+wkX/3YguEgWVn8aANPv9StEvRD9PwL2sSBaxuGobAxlauku0EQvcmem87Zil5G/Co/JdafdyIARuq3g2LiiXbSEFynOJVg6lHGPlskKYWfqOXfxIQftpG3UtZg91Eevx16MjRhSe0KiC1s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=h-partners.com; dkim=pass (1024-bit key) header.d=h-partners.com header.i=@h-partners.com header.b=KukbhkcA; arc=none smtp.client-ip=113.46.200.216 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=h-partners.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=h-partners.com header.i=@h-partners.com header.b="KukbhkcA" dkim-signature: v=1; a=rsa-sha256; d=h-partners.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=syaEbXtXRQT7GoR1+WsZALXLm43lQHNnpC9Ahas5V7o=; b=KukbhkcAQesz583MGG42zXTnuBbIG3K+O1F3naIB/Gdyc+x28PbXz4weLYuCo3KsVhIVaXciH /c96sRFVK1O7b0vTv9feIo511+7nJBD7wDFbkqzQGT/mc3Nquk2YvPw3mW6VpX+ySy5mS5Xkxnm uMaK9pCo4KrzXDOr+NY8F9Q= Received: from mail.maildlp.com (unknown [172.19.162.197]) by canpmsgout01.his.huawei.com (SkyGuard) with ESMTPS id 4fvLfG0cF0z1T4JS; Mon, 13 Apr 2026 16:48:22 +0800 (CST) Received: from kwepemf100008.china.huawei.com (unknown [7.202.181.222]) by mail.maildlp.com (Postfix) with ESMTPS id D700340576; Mon, 13 Apr 2026 16:54:19 +0800 (CST) Received: from huawei.com (10.50.87.109) by kwepemf100008.china.huawei.com (7.202.181.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Mon, 13 Apr 2026 16:54:19 +0800 From: Zeng Heng To: , , , , , , , , , , , , , , , CC: , , , Subject: [PATCH v8 next 08/10] arm_mpam: Implement dynamic reqPARTID allocation for monitoring groups Date: Mon, 13 Apr 2026 16:54:03 +0800 Message-ID: <20260413085405.1166412-9-zengheng4@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20260413085405.1166412-1-zengheng4@huawei.com> References: <20260413085405.1166412-1-zengheng4@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: kwepems100001.china.huawei.com (7.221.188.238) To kwepemf100008.china.huawei.com (7.202.181.222) Replace static reqPARTID allocation with dynamic binding to maximize the monitoring group utilization. Static allocation wastes resources when control groups create fewer sub-groups than the pre-allocated limit. Add a lookup table (reqpartid_map) to dynamically bind reqPARTIDs to control groups needing extended monitoring capacity: * resctrl_arch_rmid_expand(): Find and bind a free reqPARTID to the specified closid when creating monitoring groups. * resctrl_arch_rmid_reclaim(): Unbind reqPARTID when all monitoring groups associated with pmg are freed, making it available for reuse. Update conversion helpers for dynamic mapping: * req2intpartid() switches to lookup table for dynamic allocation. * Add partid2closid() and req_pmg2rmid() helpers. Refactor __write_config() to iterate over all reqPARTIDs that match by intPARTID, removing fixed per-closid slot assumption. Signed-off-by: Zeng Heng --- drivers/resctrl/mpam_devices.c | 21 ++--- drivers/resctrl/mpam_internal.h | 2 + drivers/resctrl/mpam_resctrl.c | 141 +++++++++++++++++++++++++++++--- include/linux/arm_mpam.h | 17 ++++ 4 files changed, 157 insertions(+), 24 deletions(-) diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c index 2aeff798a865..cf94b45b4f9e 100644 --- a/drivers/resctrl/mpam_devices.c +++ b/drivers/resctrl/mpam_devices.c @@ -1764,27 +1764,24 @@ struct mpam_write_config_arg { u16 partid; }; -static u32 get_num_reqpartid_per_intpartid(void) -{ - return (mpam_partid_max + 1) / (mpam_intpartid_max + 1); -} - static int __write_config(void *arg) { int closid_num = resctrl_arch_get_num_closid(NULL); struct mpam_write_config_arg *c = arg; - u32 reqpartid, req_idx; + u32 reqpartid; /* c->partid should be within the range of intPARTIDs */ WARN_ON_ONCE(c->partid >= closid_num); - /* Synchronize the configuration to each sub-monitoring group. */ - for (req_idx = 0; req_idx < get_num_reqpartid_per_intpartid(); - req_idx++) { - reqpartid = req_idx * closid_num + c->partid; + mpam_reprogram_ris_partid(c->ris, c->partid, + &c->comp->cfg[c->partid]); - mpam_reprogram_ris_partid(c->ris, reqpartid, - &c->comp->cfg[c->partid]); + /* Synchronize the configuration to each sub-monitoring group. */ + for (reqpartid = closid_num; + reqpartid < get_num_reqpartid(); reqpartid++) { + if (req2intpartid(reqpartid) == c->partid) + mpam_reprogram_ris_partid(c->ris, reqpartid, + &c->comp->cfg[c->partid]); } return 0; diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_internal.h index 790a90a5ccd9..16ce968344d0 100644 --- a/drivers/resctrl/mpam_internal.h +++ b/drivers/resctrl/mpam_internal.h @@ -473,6 +473,8 @@ void mpam_msmon_reset_mbwu(struct mpam_component *comp, struct mon_cfg *ctx); int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level, cpumask_t *affinity); +u32 get_num_reqpartid(void); + #ifdef CONFIG_RESCTRL_FS int mpam_resctrl_setup(void); void mpam_resctrl_exit(void); diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c index 9d0a7a4dffd1..2762462d80e5 100644 --- a/drivers/resctrl/mpam_resctrl.c +++ b/drivers/resctrl/mpam_resctrl.c @@ -268,7 +268,7 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored) * The first call occurs in update_rmid_limits(), ensuring the * prerequisite initialization is complete. */ -static u32 get_num_reqpartid(void) +u32 get_num_reqpartid(void) { struct mpam_resctrl_res *res; struct mpam_props *cprops; @@ -318,9 +318,34 @@ static u8 rmid2pmg(u32 rmid) return rmid % (mpam_pmg_max + 1); } +static u32 req_pmg2rmid(u32 reqpartid, u8 pmg) +{ + if (cdp_enabled) + reqpartid >>= 1; + + return reqpartid * (mpam_pmg_max + 1) + pmg; +} + +static u32 *reqpartid_map; + u16 req2intpartid(u16 reqpartid) { - return reqpartid % (mpam_intpartid_max + 1); + /* + * Directly return intPartid in case that mpam_reset_ris() access + * NULL pointer. + */ + if (reqpartid < (mpam_intpartid_max + 1)) + return reqpartid; + + return reqpartid_map[reqpartid]; +} + +static u32 partid2closid(u32 partid) +{ + if (cdp_enabled) + partid >>= 1; + + return partid; } /* @@ -334,12 +359,12 @@ u16 req2intpartid(u16 reqpartid) u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid) { u32 reqpartid = rmid2reqpartid(rmid); - u32 intpartid = req2intpartid(reqpartid); - if (cdp_enabled) - intpartid >>= 1; + /* When enable CDP mode, needs to filter invalid rmid entry out */ + if (reqpartid >= get_num_reqpartid()) + return U32_MAX; - if (closid != intpartid) + if (closid != partid2closid(req2intpartid(reqpartid))) return U32_MAX; return rmid; @@ -352,11 +377,9 @@ void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid) if (rmid) *rmid = idx; - if (closid) { - if (cdp_enabled) - intpartid >>= 1; - *closid = intpartid; - } + + if (closid) + *closid = partid2closid(intpartid); } void resctrl_arch_sched_in(struct task_struct *tsk) @@ -1665,6 +1688,93 @@ void mpam_resctrl_offline_cpu(unsigned int cpu) } } +static int reqpartid_init(void) +{ + int req_num, idx; + + req_num = get_num_reqpartid(); + reqpartid_map = kcalloc(req_num, sizeof(u32), GFP_KERNEL); + if (!reqpartid_map) + return -ENOMEM; + + for (idx = 0; idx < req_num; idx++) + reqpartid_map[idx] = idx; + + return 0; +} + +static void reqpartid_exit(void) +{ + kfree(reqpartid_map); +} + +static void update_rmid_entries_for_reqpartid(u32 reqpartid) +{ + int pmg; + u32 intpartid = reqpartid_map[reqpartid]; + u32 closid = partid2closid(intpartid); + + for (pmg = 0; pmg <= mpam_pmg_max; pmg++) + rmid_entry_reassign_closid(closid, req_pmg2rmid(reqpartid, pmg)); +} + +int resctrl_arch_rmid_expand(u32 closid) +{ + int i; + + for (i = resctrl_arch_get_num_closid(NULL); + i < get_num_reqpartid(); i++) { + + /* Here means the reqpartid 'i' is free. */ + if (reqpartid_map[i] >= resctrl_arch_get_num_closid(NULL)) { + if (cdp_enabled) { + reqpartid_map[i] = resctrl_get_config_index(closid, CDP_DATA); + /* + * Reqpartids are always allocated in + * pairs, never out-of-bounds access. + */ + reqpartid_map[i + 1] = resctrl_get_config_index(closid, CDP_CODE); + } else { + reqpartid_map[i] = resctrl_get_config_index(closid, CDP_NONE); + } + update_rmid_entries_for_reqpartid(i); + return i; + } + } + + return -ENOSPC; +} + +void resctrl_arch_rmid_reclaim(u32 closid, u32 rmid) +{ + int pmg; + u32 intpartid; + int reqpartid = rmid2reqpartid(rmid); + + if (reqpartid < resctrl_arch_get_num_closid(NULL)) + return; + + if (cdp_enabled) + intpartid = resctrl_get_config_index(closid, CDP_DATA); + else + intpartid = resctrl_get_config_index(closid, CDP_NONE); + + WARN_ON_ONCE(intpartid != req2intpartid(reqpartid)); + + for (pmg = 0; pmg <= mpam_pmg_max; pmg++) { + if (rmid_is_occupied(closid, req_pmg2rmid(reqpartid, pmg))) + break; + } + + if (pmg > mpam_pmg_max) { + reqpartid_map[reqpartid] = reqpartid; + if (cdp_enabled) + reqpartid_map[reqpartid + 1] = reqpartid + 1; + + update_rmid_entries_for_reqpartid(reqpartid); + } +} + int mpam_resctrl_setup(void) { int err = 0; @@ -1720,10 +1830,16 @@ int mpam_resctrl_setup(void) return -EOPNOTSUPP; } - err = resctrl_init(); + err = reqpartid_init(); if (err) return err; + err = resctrl_init(); + if (err) { + reqpartid_exit(); + return err; + } + WRITE_ONCE(resctrl_enabled, true); return 0; @@ -1741,6 +1857,7 @@ void mpam_resctrl_exit(void) WRITE_ONCE(resctrl_enabled, false); resctrl_exit(); + reqpartid_exit(); } /* diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h index f92a36187a52..d45422965907 100644 --- a/include/linux/arm_mpam.h +++ b/include/linux/arm_mpam.h @@ -59,6 +59,23 @@ void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid); void resctrl_arch_sched_in(struct task_struct *tsk); bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid); bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid); + +/** + * resctrl_arch_rmid_expand() - Expand the RMID resources for the specified closid. + * @closid: closid that matches the rmid. + * + * Return: + * 0 on success, or -ENOSPC etc on error. + */ +int resctrl_arch_rmid_expand(u32 closid); + +/** + * resctrl_arch_rmid_reclaim() - Reclaim the rmid resources for the specified closid. + * @closid: closid that matches the rmid. + * @rmid: Reclaim the rmid specified. + */ +void resctrl_arch_rmid_reclaim(u32 closid, u32 rmid); + u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid); void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid); u32 resctrl_arch_system_num_rmid_idx(void); -- 2.25.1