From nobody Mon Dec 15 22:43:16 2025 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 04C49254849 for ; Thu, 15 May 2025 16:59:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747328372; cv=none; b=KUvQESYkFZ+pbhMMxbmDbz1/MiSVMEUhQcnmXAa1+O+89M2jscNjp4g7pu6+OojicOgbhSYTB5ZS5RHaizQDIlnpPrDEjconHVXf5PPDDzOHRUXWVfqiSlKq0BqPvVQ5sgWQQJWjHcw+gz/sfwGRLCN5UK00onFTJT/pjZPsRUg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747328372; c=relaxed/simple; bh=GgkfspMOfUJyT+LNu9G40oZnTkRu1kmvAd0G2m5voXw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UIgoSTZoEteaKuBDfm637NuOP7v6+xNBFxSF6QNadAt+wsT7/ULMUMBIKI2POl49iTFyFx5NkT3jfRqic4WygIHaopeEzNz4Nuc7gG9HrCX9vezNCn/SszBwhg273j4mE3mjQCMLwmjG40VK3ez92M1mqskQ9sXBel/GpbwO32Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 631091BF3; Thu, 15 May 2025 09:59:18 -0700 (PDT) Received: from merodach.members.linode.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A38603F63F; Thu, 15 May 2025 09:59:26 -0700 (PDT) From: James Morse To: x86@kernel.org, linux-kernel@vger.kernel.org Cc: Reinette Chatre , Thomas Gleixner , Ingo Molnar , Borislav Petkov , H Peter Anvin , Babu Moger , James Morse , shameerali.kolothum.thodi@huawei.com, D Scott Phillips OS , carl@os.amperecomputing.com, lcherian@marvell.com, bobo.shaobowang@huawei.com, tan.shaopeng@fujitsu.com, baolin.wang@linux.alibaba.com, Jamie Iles , Xin Hao , peternewman@google.com, dfustini@baylibre.com, amitsinght@marvell.com, David Hildenbrand , Rex Nie , Dave Martin , Koba Ko , Shanker Donthineni , fenghuay@nvidia.com, Shaopeng Tan , Babu Moger , Tony Luck Subject: [PATCH v12 05/25] x86/resctrl: Remove the limit on the number of CLOSID Date: Thu, 15 May 2025 16:58:35 +0000 Message-Id: <20250515165855.31452-6-james.morse@arm.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20250515165855.31452-1-james.morse@arm.com> References: <20250515165855.31452-1-james.morse@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Amit Singh Tomar Resctrl allocates and finds free CLOSID values using the bits of a u32. This restricts the number of control groups that can be created by user-space. MPAM has an architectural limit of 2^16 CLOSID values, Intel x86 could be extended beyond 32 values. There is at least one MPAM platform which supports more than 32 CLOSID values. Replace the fixed size bitmap with calls to the bitmap API to allocate an array of a sufficient size. ffs() returns '1' for bit 0, hence the existing code subtracts 1 from the index to get the CLOSID value. find_first_bit() returns the bit number which does not need adjusting. Signed-off-by: Amit Singh Tomar [ morse: fixed the off-by-one in the allocator and the wrong not-found value. Removed the limit. Rephrase the commit message. ] Signed-off-by: James Morse Tested-by: Peter Newman Tested-by: Shaopeng Tan Tested-by: Amit Singh Tomar # arm64 Tested-by: Shanker Donthineni # arm64 Tested-by: Babu Moger Tested-by: Tony Luck Reviewed-by: Fenghua Yu Reviewed-by: Reinette Chatre --- Changes since v8: * Added check for closid_init() on monitor only platforms. Changes since v7: * Moved closid_exit() earlier in rdt_kill_sb() to match what rdt_get_tree() does. Changes since v6: * Set variable to NULL after kfree()ing it. * Call closid_exit() from rdt_kill_sb() to prevent a memory leak. Changes since v5: * This patch got pulled into this series. --- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 51 ++++++++++++++++++-------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/r= esctrl/rdtgroup.c index cc4a54145c83..53213cae30ec 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -130,8 +130,8 @@ static bool resctrl_is_mbm_event(int e) } =20 /* - * Trivial allocator for CLOSIDs. Since h/w only supports a small number, - * we can keep a bitmap of free CLOSIDs in a single integer. + * Trivial allocator for CLOSIDs. Use BITMAP APIs to manipulate a bitmap + * of free CLOSIDs. * * Using a global CLOSID across all resources has some advantages and * some drawbacks: @@ -144,7 +144,7 @@ static bool resctrl_is_mbm_event(int e) * - Our choices on how to configure each resource become progressively mo= re * limited as the number of resources grows. */ -static unsigned long closid_free_map; +static unsigned long *closid_free_map; static int closid_free_map_len; =20 int closids_supported(void) @@ -152,20 +152,35 @@ int closids_supported(void) return closid_free_map_len; } =20 -static void closid_init(void) +static int closid_init(void) { struct resctrl_schema *s; - u32 rdt_min_closid =3D 32; + u32 rdt_min_closid =3D ~0; + + /* Monitor only platforms still call closid_init() */ + if (list_empty(&resctrl_schema_all)) + return 0; =20 /* Compute rdt_min_closid across all resources */ list_for_each_entry(s, &resctrl_schema_all, list) rdt_min_closid =3D min(rdt_min_closid, s->num_closid); =20 - closid_free_map =3D BIT_MASK(rdt_min_closid) - 1; + closid_free_map =3D bitmap_alloc(rdt_min_closid, GFP_KERNEL); + if (!closid_free_map) + return -ENOMEM; + bitmap_fill(closid_free_map, rdt_min_closid); =20 /* RESCTRL_RESERVED_CLOSID is always reserved for the default group */ - __clear_bit(RESCTRL_RESERVED_CLOSID, &closid_free_map); + __clear_bit(RESCTRL_RESERVED_CLOSID, closid_free_map); closid_free_map_len =3D rdt_min_closid; + + return 0; +} + +static void closid_exit(void) +{ + bitmap_free(closid_free_map); + closid_free_map =3D NULL; } =20 static int closid_alloc(void) @@ -182,12 +197,11 @@ static int closid_alloc(void) return cleanest_closid; closid =3D cleanest_closid; } else { - closid =3D ffs(closid_free_map); - if (closid =3D=3D 0) + closid =3D find_first_bit(closid_free_map, closid_free_map_len); + if (closid =3D=3D closid_free_map_len) return -ENOSPC; - closid--; } - __clear_bit(closid, &closid_free_map); + __clear_bit(closid, closid_free_map); =20 return closid; } @@ -196,7 +210,7 @@ void closid_free(int closid) { lockdep_assert_held(&rdtgroup_mutex); =20 - __set_bit(closid, &closid_free_map); + __set_bit(closid, closid_free_map); } =20 /** @@ -210,7 +224,7 @@ bool closid_allocated(unsigned int closid) { lockdep_assert_held(&rdtgroup_mutex); =20 - return !test_bit(closid, &closid_free_map); + return !test_bit(closid, closid_free_map); } =20 /** @@ -2765,20 +2779,22 @@ static int rdt_get_tree(struct fs_context *fc) goto out_ctx; } =20 - closid_init(); + ret =3D closid_init(); + if (ret) + goto out_schemata_free; =20 if (resctrl_arch_mon_capable()) flags |=3D RFTYPE_MON; =20 ret =3D rdtgroup_add_files(rdtgroup_default.kn, flags); if (ret) - goto out_schemata_free; + goto out_closid_exit; =20 kernfs_activate(rdtgroup_default.kn); =20 ret =3D rdtgroup_create_info_dir(rdtgroup_default.kn); if (ret < 0) - goto out_schemata_free; + goto out_closid_exit; =20 if (resctrl_arch_mon_capable()) { ret =3D mongroup_create_dir(rdtgroup_default.kn, @@ -2829,6 +2845,8 @@ static int rdt_get_tree(struct fs_context *fc) kernfs_remove(kn_mongrp); out_info: kernfs_remove(kn_info); +out_closid_exit: + closid_exit(); out_schemata_free: schemata_list_destroy(); out_ctx: @@ -3076,6 +3094,7 @@ static void rdt_kill_sb(struct super_block *sb) rmdir_all_sub(); rdt_pseudo_lock_release(); rdtgroup_default.mode =3D RDT_MODE_SHAREABLE; + closid_exit(); schemata_list_destroy(); rdtgroup_destroy_root(); if (resctrl_arch_alloc_capable()) --=20 2.39.5