hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/powerpc/kernel/eeh_event.c
....@@ -1,17 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
2
- * This program is free software; you can redistribute it and/or modify
3
- * it under the terms of the GNU General Public License as published by
4
- * the Free Software Foundation; either version 2 of the License, or
5
- * (at your option) any later version.
6
- *
7
- * This program is distributed in the hope that it will be useful,
8
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
- * GNU General Public License for more details.
11
- *
12
- * You should have received a copy of the GNU General Public License
13
- * along with this program; if not, write to the Free Software
14
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
153 *
164 * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
175 */
....@@ -35,7 +23,7 @@
3523 */
3624
3725 static DEFINE_SPINLOCK(eeh_eventlist_lock);
38
-static struct semaphore eeh_eventlist_sem;
26
+static DECLARE_COMPLETION(eeh_eventlist_event);
3927 static LIST_HEAD(eeh_eventlist);
4028
4129 /**
....@@ -52,10 +40,9 @@
5240 {
5341 unsigned long flags;
5442 struct eeh_event *event;
55
- struct eeh_pe *pe;
5643
5744 while (!kthread_should_stop()) {
58
- if (down_interruptible(&eeh_eventlist_sem))
45
+ if (wait_for_completion_interruptible(&eeh_eventlist_event))
5946 break;
6047
6148 /* Fetch EEH event from the queue */
....@@ -71,19 +58,10 @@
7158 continue;
7259
7360 /* We might have event without binding PE */
74
- pe = event->pe;
75
- if (pe) {
76
- if (pe->type & EEH_PE_PHB)
77
- pr_info("EEH: Detected error on PHB#%x\n",
78
- pe->phb->global_number);
79
- else
80
- pr_info("EEH: Detected PCI bus error on "
81
- "PHB#%x-PE#%x\n",
82
- pe->phb->global_number, pe->addr);
83
- eeh_handle_normal_event(pe);
84
- } else {
61
+ if (event->pe)
62
+ eeh_handle_normal_event(event->pe);
63
+ else
8564 eeh_handle_special_event();
86
- }
8765
8866 kfree(event);
8967 }
....@@ -101,9 +79,6 @@
10179 {
10280 struct task_struct *t;
10381 int ret = 0;
104
-
105
- /* Initialize semaphore */
106
- sema_init(&eeh_eventlist_sem, 0);
10782
10883 t = kthread_run(eeh_event_handler, NULL, "eehd");
10984 if (IS_ERR(t)) {
....@@ -124,7 +99,7 @@
12499 * the actual event will be delivered in a normal context
125100 * (from a workqueue).
126101 */
127
-int eeh_send_failure_event(struct eeh_pe *pe)
102
+int __eeh_send_failure_event(struct eeh_pe *pe)
128103 {
129104 unsigned long flags;
130105 struct eeh_event *event;
....@@ -136,17 +111,49 @@
136111 }
137112 event->pe = pe;
138113
114
+ /*
115
+ * Mark the PE as recovering before inserting it in the queue.
116
+ * This prevents the PE from being free()ed by a hotplug driver
117
+ * while the PE is sitting in the event queue.
118
+ */
119
+ if (pe) {
120
+#ifdef CONFIG_STACKTRACE
121
+ /*
122
+ * Save the current stack trace so we can dump it from the
123
+ * event handler thread.
124
+ */
125
+ pe->trace_entries = stack_trace_save(pe->stack_trace,
126
+ ARRAY_SIZE(pe->stack_trace), 0);
127
+#endif /* CONFIG_STACKTRACE */
128
+
129
+ eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
130
+ }
131
+
139132 /* We may or may not be called in an interrupt context */
140133 spin_lock_irqsave(&eeh_eventlist_lock, flags);
141134 list_add(&event->list, &eeh_eventlist);
142135 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
143136
144137 /* For EEH deamon to knick in */
145
- up(&eeh_eventlist_sem);
138
+ complete(&eeh_eventlist_event);
146139
147140 return 0;
148141 }
149142
143
+int eeh_send_failure_event(struct eeh_pe *pe)
144
+{
145
+ /*
146
+ * If we've manually supressed recovery events via debugfs
147
+ * then just drop it on the floor.
148
+ */
149
+ if (eeh_debugfs_no_recover) {
150
+ pr_err("EEH: Event dropped due to no_recover setting\n");
151
+ return 0;
152
+ }
153
+
154
+ return __eeh_send_failure_event(pe);
155
+}
156
+
150157 /**
151158 * eeh_remove_event - Remove EEH event from the queue
152159 * @pe: Event binding to the PE