Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

James Morse and committed by
Catalin Marinas
3bd04fe7 475228d1

+54 -3
+54 -3
drivers/resctrl/mpam_devices.c
··· 808 808 809 809 /* 810 810 * Called via smp_call_on_cpu() to prevent migration, while still being 811 - * pre-emptible. 811 + * pre-emptible. Caller must hold mpam_srcu. 812 812 */ 813 813 static int mpam_reset_ris(void *arg) 814 814 { 815 815 u16 partid, partid_max; 816 816 struct mpam_msc_ris *ris = arg; 817 - 818 - WARN_ON_ONCE(!srcu_read_lock_held((&mpam_srcu))); 819 817 820 818 if (ris->in_reset_state) 821 819 return 0; ··· 1335 1337 mpam_partid_max + 1, mpam_pmg_max + 1); 1336 1338 } 1337 1339 1340 + static void mpam_reset_component_locked(struct mpam_component *comp) 1341 + { 1342 + struct mpam_vmsc *vmsc; 1343 + 1344 + lockdep_assert_cpus_held(); 1345 + 1346 + guard(srcu)(&mpam_srcu); 1347 + list_for_each_entry_srcu(vmsc, &comp->vmsc, comp_list, 1348 + srcu_read_lock_held(&mpam_srcu)) { 1349 + struct mpam_msc *msc = vmsc->msc; 1350 + struct mpam_msc_ris *ris; 1351 + 1352 + list_for_each_entry_srcu(ris, &vmsc->ris, vmsc_list, 1353 + srcu_read_lock_held(&mpam_srcu)) { 1354 + if (!ris->in_reset_state) 1355 + mpam_touch_msc(msc, mpam_reset_ris, ris); 1356 + ris->in_reset_state = true; 1357 + } 1358 + } 1359 + } 1360 + 1361 + static void mpam_reset_class_locked(struct mpam_class *class) 1362 + { 1363 + struct mpam_component *comp; 1364 + 1365 + lockdep_assert_cpus_held(); 1366 + 1367 + guard(srcu)(&mpam_srcu); 1368 + list_for_each_entry_srcu(comp, &class->components, class_list, 1369 + srcu_read_lock_held(&mpam_srcu)) 1370 + mpam_reset_component_locked(comp); 1371 + } 1372 + 1373 + static void mpam_reset_class(struct mpam_class *class) 1374 + { 1375 + cpus_read_lock(); 1376 + mpam_reset_class_locked(class); 1377 + cpus_read_unlock(); 1378 + } 1379 + 1380 + /* 1381 + * Called in response to an error IRQ. 1382 + * All of MPAMs errors indicate a software bug, restore any modified 1383 + * controls to their reset values. 1384 + */ 1338 1385 void mpam_disable(struct work_struct *ignored) 1339 1386 { 1387 + int idx; 1388 + struct mpam_class *class; 1340 1389 struct mpam_msc *msc, *tmp; 1341 1390 1342 1391 mutex_lock(&mpam_cpuhp_state_lock); ··· 1392 1347 mpam_cpuhp_state = 0; 1393 1348 } 1394 1349 mutex_unlock(&mpam_cpuhp_state_lock); 1350 + 1351 + idx = srcu_read_lock(&mpam_srcu); 1352 + list_for_each_entry_srcu(class, &mpam_classes, classes_list, 1353 + srcu_read_lock_held(&mpam_srcu)) 1354 + mpam_reset_class(class); 1355 + srcu_read_unlock(&mpam_srcu, idx); 1395 1356 1396 1357 mutex_lock(&mpam_list_lock); 1397 1358 list_for_each_entry_safe(msc, tmp, &mpam_all_msc, all_msc_list)