Skip to content

Commit 3bd04fe

Browse files
James Morsectmarinas
authored andcommitted
arm_mpam: Extend reset logic to allow devices to be reset any time
cpuhp callbacks aren't the only time the MSC configuration may need to be reset. Resctrl has an API call to reset a class. If an MPAM error interrupt arrives it indicates the driver has misprogrammed an MSC. The safest thing to do is reset all the MSCs and disable MPAM. Add a helper to reset RIS via their class. Call this from mpam_disable(), which can be scheduled from the error interrupt handler. Signed-off-by: James Morse <james.morse@arm.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Reviewed-by: Ben Horgan <ben.horgan@arm.com> Reviewed-by: Gavin Shan <gshan@redhat.com> Reviewed-by: Fenghua Yu <fenghuay@nvidia.com> Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Tested-by: Fenghua Yu <fenghuay@nvidia.com> Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com> Tested-by: Peter Newman <peternewman@google.com> Tested-by: Carl Worth <carl@os.amperecomputing.com> Tested-by: Gavin Shan <gshan@redhat.com> Tested-by: Zeng Heng <zengheng4@huawei.com> Tested-by: Hanjun Guo <guohanjun@huawei.com> Signed-off-by: Ben Horgan <ben.horgan@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent 475228d commit 3bd04fe

1 file changed

Lines changed: 54 additions & 3 deletions

File tree

drivers/resctrl/mpam_devices.c

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -808,15 +808,13 @@ static void mpam_reset_ris_partid(struct mpam_msc_ris *ris, u16 partid)
808808

809809
/*
810810
* Called via smp_call_on_cpu() to prevent migration, while still being
811-
* pre-emptible.
811+
* pre-emptible. Caller must hold mpam_srcu.
812812
*/
813813
static int mpam_reset_ris(void *arg)
814814
{
815815
u16 partid, partid_max;
816816
struct mpam_msc_ris *ris = arg;
817817

818-
WARN_ON_ONCE(!srcu_read_lock_held((&mpam_srcu)));
819-
820818
if (ris->in_reset_state)
821819
return 0;
822820

@@ -1337,8 +1335,55 @@ static void mpam_enable_once(void)
13371335
mpam_partid_max + 1, mpam_pmg_max + 1);
13381336
}
13391337

1338+
static void mpam_reset_component_locked(struct mpam_component *comp)
1339+
{
1340+
struct mpam_vmsc *vmsc;
1341+
1342+
lockdep_assert_cpus_held();
1343+
1344+
guard(srcu)(&mpam_srcu);
1345+
list_for_each_entry_srcu(vmsc, &comp->vmsc, comp_list,
1346+
srcu_read_lock_held(&mpam_srcu)) {
1347+
struct mpam_msc *msc = vmsc->msc;
1348+
struct mpam_msc_ris *ris;
1349+
1350+
list_for_each_entry_srcu(ris, &vmsc->ris, vmsc_list,
1351+
srcu_read_lock_held(&mpam_srcu)) {
1352+
if (!ris->in_reset_state)
1353+
mpam_touch_msc(msc, mpam_reset_ris, ris);
1354+
ris->in_reset_state = true;
1355+
}
1356+
}
1357+
}
1358+
1359+
static void mpam_reset_class_locked(struct mpam_class *class)
1360+
{
1361+
struct mpam_component *comp;
1362+
1363+
lockdep_assert_cpus_held();
1364+
1365+
guard(srcu)(&mpam_srcu);
1366+
list_for_each_entry_srcu(comp, &class->components, class_list,
1367+
srcu_read_lock_held(&mpam_srcu))
1368+
mpam_reset_component_locked(comp);
1369+
}
1370+
1371+
static void mpam_reset_class(struct mpam_class *class)
1372+
{
1373+
cpus_read_lock();
1374+
mpam_reset_class_locked(class);
1375+
cpus_read_unlock();
1376+
}
1377+
1378+
/*
1379+
* Called in response to an error IRQ.
1380+
* All of MPAMs errors indicate a software bug, restore any modified
1381+
* controls to their reset values.
1382+
*/
13401383
void mpam_disable(struct work_struct *ignored)
13411384
{
1385+
int idx;
1386+
struct mpam_class *class;
13421387
struct mpam_msc *msc, *tmp;
13431388

13441389
mutex_lock(&mpam_cpuhp_state_lock);
@@ -1348,6 +1393,12 @@ void mpam_disable(struct work_struct *ignored)
13481393
}
13491394
mutex_unlock(&mpam_cpuhp_state_lock);
13501395

1396+
idx = srcu_read_lock(&mpam_srcu);
1397+
list_for_each_entry_srcu(class, &mpam_classes, classes_list,
1398+
srcu_read_lock_held(&mpam_srcu))
1399+
mpam_reset_class(class);
1400+
srcu_read_unlock(&mpam_srcu, idx);
1401+
13511402
mutex_lock(&mpam_list_lock);
13521403
list_for_each_entry_safe(msc, tmp, &mpam_all_msc, all_msc_list)
13531404
mpam_msc_destroy(msc);

0 commit comments

Comments
 (0)