Skip to content

Commit dcb1d3d

Browse files
Amit Singh Tomarbp3tk0v
authored andcommitted
x86/resctrl: Remove the limit on the number of CLOSID
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. [ 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: Amit Singh Tomar <amitsinght@marvell.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Fenghua Yu <fenghuay@nvidia.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Tested-by: Fenghua Yu <fenghuay@nvidia.com> Tested-by: Peter Newman <peternewman@google.com> Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Tested-by: Amit Singh Tomar <amitsinght@marvell.com> # arm64 Tested-by: Shanker Donthineni <sdonthineni@nvidia.com> # arm64 Tested-by: Babu Moger <babu.moger@amd.com> Tested-by: Tony Luck <tony.luck@intel.com> Link: https://lore.kernel.org/20250515165855.31452-6-james.morse@arm.com
1 parent 94f7531 commit dcb1d3d

File tree

1 file changed

+35
-16
lines changed

1 file changed

+35
-16
lines changed

arch/x86/kernel/cpu/resctrl/rdtgroup.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ static bool resctrl_is_mbm_event(int e)
130130
}
131131

132132
/*
133-
* Trivial allocator for CLOSIDs. Since h/w only supports a small number,
134-
* we can keep a bitmap of free CLOSIDs in a single integer.
133+
* Trivial allocator for CLOSIDs. Use BITMAP APIs to manipulate a bitmap
134+
* of free CLOSIDs.
135135
*
136136
* Using a global CLOSID across all resources has some advantages and
137137
* some drawbacks:
@@ -144,28 +144,43 @@ static bool resctrl_is_mbm_event(int e)
144144
* - Our choices on how to configure each resource become progressively more
145145
* limited as the number of resources grows.
146146
*/
147-
static unsigned long closid_free_map;
147+
static unsigned long *closid_free_map;
148148
static int closid_free_map_len;
149149

150150
int closids_supported(void)
151151
{
152152
return closid_free_map_len;
153153
}
154154

155-
static void closid_init(void)
155+
static int closid_init(void)
156156
{
157157
struct resctrl_schema *s;
158-
u32 rdt_min_closid = 32;
158+
u32 rdt_min_closid = ~0;
159+
160+
/* Monitor only platforms still call closid_init() */
161+
if (list_empty(&resctrl_schema_all))
162+
return 0;
159163

160164
/* Compute rdt_min_closid across all resources */
161165
list_for_each_entry(s, &resctrl_schema_all, list)
162166
rdt_min_closid = min(rdt_min_closid, s->num_closid);
163167

164-
closid_free_map = BIT_MASK(rdt_min_closid) - 1;
168+
closid_free_map = bitmap_alloc(rdt_min_closid, GFP_KERNEL);
169+
if (!closid_free_map)
170+
return -ENOMEM;
171+
bitmap_fill(closid_free_map, rdt_min_closid);
165172

166173
/* RESCTRL_RESERVED_CLOSID is always reserved for the default group */
167-
__clear_bit(RESCTRL_RESERVED_CLOSID, &closid_free_map);
174+
__clear_bit(RESCTRL_RESERVED_CLOSID, closid_free_map);
168175
closid_free_map_len = rdt_min_closid;
176+
177+
return 0;
178+
}
179+
180+
static void closid_exit(void)
181+
{
182+
bitmap_free(closid_free_map);
183+
closid_free_map = NULL;
169184
}
170185

171186
static int closid_alloc(void)
@@ -182,12 +197,11 @@ static int closid_alloc(void)
182197
return cleanest_closid;
183198
closid = cleanest_closid;
184199
} else {
185-
closid = ffs(closid_free_map);
186-
if (closid == 0)
200+
closid = find_first_bit(closid_free_map, closid_free_map_len);
201+
if (closid == closid_free_map_len)
187202
return -ENOSPC;
188-
closid--;
189203
}
190-
__clear_bit(closid, &closid_free_map);
204+
__clear_bit(closid, closid_free_map);
191205

192206
return closid;
193207
}
@@ -196,7 +210,7 @@ void closid_free(int closid)
196210
{
197211
lockdep_assert_held(&rdtgroup_mutex);
198212

199-
__set_bit(closid, &closid_free_map);
213+
__set_bit(closid, closid_free_map);
200214
}
201215

202216
/**
@@ -210,7 +224,7 @@ bool closid_allocated(unsigned int closid)
210224
{
211225
lockdep_assert_held(&rdtgroup_mutex);
212226

213-
return !test_bit(closid, &closid_free_map);
227+
return !test_bit(closid, closid_free_map);
214228
}
215229

216230
/**
@@ -2765,20 +2779,22 @@ static int rdt_get_tree(struct fs_context *fc)
27652779
goto out_ctx;
27662780
}
27672781

2768-
closid_init();
2782+
ret = closid_init();
2783+
if (ret)
2784+
goto out_schemata_free;
27692785

27702786
if (resctrl_arch_mon_capable())
27712787
flags |= RFTYPE_MON;
27722788

27732789
ret = rdtgroup_add_files(rdtgroup_default.kn, flags);
27742790
if (ret)
2775-
goto out_schemata_free;
2791+
goto out_closid_exit;
27762792

27772793
kernfs_activate(rdtgroup_default.kn);
27782794

27792795
ret = rdtgroup_create_info_dir(rdtgroup_default.kn);
27802796
if (ret < 0)
2781-
goto out_schemata_free;
2797+
goto out_closid_exit;
27822798

27832799
if (resctrl_arch_mon_capable()) {
27842800
ret = mongroup_create_dir(rdtgroup_default.kn,
@@ -2829,6 +2845,8 @@ static int rdt_get_tree(struct fs_context *fc)
28292845
kernfs_remove(kn_mongrp);
28302846
out_info:
28312847
kernfs_remove(kn_info);
2848+
out_closid_exit:
2849+
closid_exit();
28322850
out_schemata_free:
28332851
schemata_list_destroy();
28342852
out_ctx:
@@ -3076,6 +3094,7 @@ static void rdt_kill_sb(struct super_block *sb)
30763094
rmdir_all_sub();
30773095
rdt_pseudo_lock_release();
30783096
rdtgroup_default.mode = RDT_MODE_SHAREABLE;
3097+
closid_exit();
30793098
schemata_list_destroy();
30803099
rdtgroup_destroy_root();
30813100
if (resctrl_arch_alloc_capable())

0 commit comments

Comments
 (0)