History

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.

James Morse committed 12 months ago

Commit 3bd04fe1 parent 475228d1 file · +54 −3Browse files

Showing the changes to drivers/resctrl (1 of 1 file). Show all

Unified · Split

drivers/resctrl/mpam_devices.c+54−3
@@ -808,15 +808,13 @@ static void mpam_reset_ris_partid(struct mpam_msc_ris *ris, u16 partid) · 807 unmodified lines
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) · 514 unmodified lines
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) · 3 unmodified lines
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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t