Skip to content

Commit b30a55d

Browse files
James Morsebp3tk0v
authored andcommitted
x86/resctrl: Track the number of dirty RMID a CLOSID has
MPAM's PMG bits extend its PARTID space, meaning the same PMG value can be used for different control groups. This means once a CLOSID is allocated, all its monitoring ids may still be dirty, and held in limbo. Keep track of the number of RMID held in limbo each CLOSID has. This will allow a future helper to find the 'cleanest' CLOSID when allocating. The array is only needed when CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID is defined. This will never be the case on x86. Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Shaopeng Tan <tan.shaopeng@fujitsu.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Reviewed-by: Babu Moger <babu.moger@amd.com> Tested-by: Shaopeng Tan <tan.shaopeng@fujitsu.com> Tested-by: Peter Newman <peternewman@google.com> Tested-by: Babu Moger <babu.moger@amd.com> Tested-by: Carl Worth <carl@os.amperecomputing.com> # arm64 Link: https://lore.kernel.org/r/20240213184438.16675-9-james.morse@arm.com Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
1 parent c4c0376 commit b30a55d

1 file changed

Lines changed: 65 additions & 10 deletions

File tree

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

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ struct rmid_entry {
5050
*/
5151
static LIST_HEAD(rmid_free_lru);
5252

53+
/*
54+
* @closid_num_dirty_rmid The number of dirty RMID each CLOSID has.
55+
* Only allocated when CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID is defined.
56+
* Indexed by CLOSID. Protected by rdtgroup_mutex.
57+
*/
58+
static u32 *closid_num_dirty_rmid;
59+
5360
/*
5461
* @rmid_limbo_count - count of currently unused but (potentially)
5562
* dirty RMIDs.
@@ -292,6 +299,17 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d,
292299
return 0;
293300
}
294301

302+
static void limbo_release_entry(struct rmid_entry *entry)
303+
{
304+
lockdep_assert_held(&rdtgroup_mutex);
305+
306+
rmid_limbo_count--;
307+
list_add_tail(&entry->list, &rmid_free_lru);
308+
309+
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
310+
closid_num_dirty_rmid[entry->closid]--;
311+
}
312+
295313
/*
296314
* Check the RMIDs that are marked as busy for this domain. If the
297315
* reported LLC occupancy is below the threshold clear the busy bit and
@@ -328,10 +346,8 @@ void __check_limbo(struct rdt_domain *d, bool force_free)
328346

329347
if (force_free || !rmid_dirty) {
330348
clear_bit(idx, d->rmid_busy_llc);
331-
if (!--entry->busy) {
332-
rmid_limbo_count--;
333-
list_add_tail(&entry->list, &rmid_free_lru);
334-
}
349+
if (!--entry->busy)
350+
limbo_release_entry(entry);
335351
}
336352
cur_idx = idx + 1;
337353
}
@@ -398,6 +414,8 @@ static void add_rmid_to_limbo(struct rmid_entry *entry)
398414
u64 val = 0;
399415
u32 idx;
400416

417+
lockdep_assert_held(&rdtgroup_mutex);
418+
401419
idx = resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid);
402420

403421
entry->busy = 0;
@@ -423,10 +441,13 @@ static void add_rmid_to_limbo(struct rmid_entry *entry)
423441
}
424442
put_cpu();
425443

426-
if (entry->busy)
444+
if (entry->busy) {
427445
rmid_limbo_count++;
428-
else
446+
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
447+
closid_num_dirty_rmid[entry->closid]++;
448+
} else {
429449
list_add_tail(&entry->list, &rmid_free_lru);
450+
}
430451
}
431452

432453
void free_rmid(u32 closid, u32 rmid)
@@ -770,13 +791,39 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms)
770791
static int dom_data_init(struct rdt_resource *r)
771792
{
772793
u32 idx_limit = resctrl_arch_system_num_rmid_idx();
794+
u32 num_closid = resctrl_arch_get_num_closid(r);
773795
struct rmid_entry *entry = NULL;
796+
int err = 0, i;
774797
u32 idx;
775-
int i;
798+
799+
mutex_lock(&rdtgroup_mutex);
800+
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
801+
u32 *tmp;
802+
803+
/*
804+
* If the architecture hasn't provided a sanitised value here,
805+
* this may result in larger arrays than necessary. Resctrl will
806+
* use a smaller system wide value based on the resources in
807+
* use.
808+
*/
809+
tmp = kcalloc(num_closid, sizeof(*tmp), GFP_KERNEL);
810+
if (!tmp) {
811+
err = -ENOMEM;
812+
goto out_unlock;
813+
}
814+
815+
closid_num_dirty_rmid = tmp;
816+
}
776817

777818
rmid_ptrs = kcalloc(idx_limit, sizeof(struct rmid_entry), GFP_KERNEL);
778-
if (!rmid_ptrs)
779-
return -ENOMEM;
819+
if (!rmid_ptrs) {
820+
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
821+
kfree(closid_num_dirty_rmid);
822+
closid_num_dirty_rmid = NULL;
823+
}
824+
err = -ENOMEM;
825+
goto out_unlock;
826+
}
780827

781828
for (i = 0; i < idx_limit; i++) {
782829
entry = &rmid_ptrs[i];
@@ -796,13 +843,21 @@ static int dom_data_init(struct rdt_resource *r)
796843
entry = __rmid_entry(idx);
797844
list_del(&entry->list);
798845

799-
return 0;
846+
out_unlock:
847+
mutex_unlock(&rdtgroup_mutex);
848+
849+
return err;
800850
}
801851

802852
static void __exit dom_data_exit(void)
803853
{
804854
mutex_lock(&rdtgroup_mutex);
805855

856+
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID)) {
857+
kfree(closid_num_dirty_rmid);
858+
closid_num_dirty_rmid = NULL;
859+
}
860+
806861
kfree(rmid_ptrs);
807862
rmid_ptrs = NULL;
808863

0 commit comments

Comments
 (0)