From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Oliver O'Halloran <oohall@gmail.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Sasha Levin <sashal@kernel.org>,
linuxppc-dev@lists.ozlabs.org
Subject: [PATCH AUTOSEL 5.3 68/87] powerpc/eeh: Clean up EEH PEs after recovery finishes
Date: Tue, 24 Sep 2019 12:41:24 -0400 [thread overview]
Message-ID: <20190924164144.25591-68-sashal@kernel.org> (raw)
In-Reply-To: <20190924164144.25591-1-sashal@kernel.org>
From: Oliver O'Halloran <oohall@gmail.com>
[ Upstream commit 799abe283e5103d48e079149579b4f167c95ea0e ]
When the last device in an eeh_pe is removed the eeh_pe structure itself
(and any empty parents) are freed since they are no longer needed. This
results in a crash when a hotplug driver is involved since the following
may occur:
1. Device is suprise removed.
2. Driver performs an MMIO, which fails and queues and eeh_event.
3. Hotplug driver receives a hotplug interrupt and removes any
pci_devs that were under the slot.
4. pci_dev is torn down and the eeh_pe is freed.
5. The EEH event handler thread processes the eeh_event and crashes
since the eeh_pe pointer in the eeh_event structure is no
longer valid.
Crashing is generally considered poor form. Instead of doing that use
the fact PEs are marked as EEH_PE_INVALID to keep them around until the
end of the recovery cycle, at which point we can safely prune any empty
PEs.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190903101605.2890-2-oohall@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/eeh_driver.c | 36 ++++++++++++++++++++++++++++++--
arch/powerpc/kernel/eeh_event.c | 8 +++++++
arch/powerpc/kernel/eeh_pe.c | 23 +++++++++++++++++++-
3 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 1fbe541856f5e..fe0c32fb9f96f 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -744,6 +744,33 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
*/
#define MAX_WAIT_FOR_RECOVERY 300
+
+/* Walks the PE tree after processing an event to remove any stale PEs.
+ *
+ * NB: This needs to be recursive to ensure the leaf PEs get removed
+ * before their parents do. Although this is possible to do recursively
+ * we don't since this is easier to read and we need to garantee
+ * the leaf nodes will be handled first.
+ */
+static void eeh_pe_cleanup(struct eeh_pe *pe)
+{
+ struct eeh_pe *child_pe, *tmp;
+
+ list_for_each_entry_safe(child_pe, tmp, &pe->child_list, child)
+ eeh_pe_cleanup(child_pe);
+
+ if (pe->state & EEH_PE_KEEP)
+ return;
+
+ if (!(pe->state & EEH_PE_INVALID))
+ return;
+
+ if (list_empty(&pe->edevs) && list_empty(&pe->child_list)) {
+ list_del(&pe->child);
+ kfree(pe);
+ }
+}
+
/**
* eeh_handle_normal_event - Handle EEH events on a specific PE
* @pe: EEH PE - which should not be used after we return, as it may
@@ -782,8 +809,6 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
return;
}
- eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
-
eeh_pe_update_time_stamp(pe);
pe->freeze_count++;
if (pe->freeze_count > eeh_max_freezes) {
@@ -973,6 +998,12 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
return;
}
}
+
+ /*
+ * Clean up any PEs without devices. While marked as EEH_PE_RECOVERYING
+ * we don't want to modify the PE tree structure so we do it here.
+ */
+ eeh_pe_cleanup(pe);
eeh_pe_state_clear(pe, EEH_PE_RECOVERING, true);
}
@@ -1045,6 +1076,7 @@ void eeh_handle_special_event(void)
*/
if (rc == EEH_NEXT_ERR_FROZEN_PE ||
rc == EEH_NEXT_ERR_FENCED_PHB) {
+ eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
eeh_handle_normal_event(pe);
} else {
pci_lock_rescan_remove();
diff --git a/arch/powerpc/kernel/eeh_event.c b/arch/powerpc/kernel/eeh_event.c
index 64cfbe41174b2..e36653e5f76b3 100644
--- a/arch/powerpc/kernel/eeh_event.c
+++ b/arch/powerpc/kernel/eeh_event.c
@@ -121,6 +121,14 @@ int __eeh_send_failure_event(struct eeh_pe *pe)
}
event->pe = pe;
+ /*
+ * Mark the PE as recovering before inserting it in the queue.
+ * This prevents the PE from being free()ed by a hotplug driver
+ * while the PE is sitting in the event queue.
+ */
+ if (pe)
+ eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
+
/* We may or may not be called in an interrupt context */
spin_lock_irqsave(&eeh_eventlist_lock, flags);
list_add(&event->list, &eeh_eventlist);
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index 854cef7b18f4d..f0813d50e0b1c 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -491,6 +491,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
{
struct eeh_pe *pe, *parent, *child;
+ bool keep, recover;
int cnt;
struct pci_dn *pdn = eeh_dev_to_pdn(edev);
@@ -516,10 +517,21 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
*/
while (1) {
parent = pe->parent;
+
+ /* PHB PEs should never be removed */
if (pe->type & EEH_PE_PHB)
break;
- if (!(pe->state & EEH_PE_KEEP)) {
+ /*
+ * XXX: KEEP is set while resetting a PE. I don't think it's
+ * ever set without RECOVERING also being set. I could
+ * be wrong though so catch that with a WARN.
+ */
+ keep = !!(pe->state & EEH_PE_KEEP);
+ recover = !!(pe->state & EEH_PE_RECOVERING);
+ WARN_ON(keep && !recover);
+
+ if (!keep && !recover) {
if (list_empty(&pe->edevs) &&
list_empty(&pe->child_list)) {
list_del(&pe->child);
@@ -528,6 +540,15 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
break;
}
} else {
+ /*
+ * Mark the PE as invalid. At the end of the recovery
+ * process any invalid PEs will be garbage collected.
+ *
+ * We need to delay the free()ing of them since we can
+ * remove edev's while traversing the PE tree which
+ * might trigger the removal of a PE and we can't
+ * deal with that (yet).
+ */
if (list_empty(&pe->edevs)) {
cnt = 0;
list_for_each_entry(child, &pe->child_list, child) {
--
2.20.1
next prev parent reply other threads:[~2019-09-24 17:00 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-24 16:40 [PATCH AUTOSEL 5.3 01/87] drm/vkms: Fix crc worker races Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 02/87] drm/mcde: Fix uninitialized variable Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 03/87] drm/bridge: tc358767: Increase AUX transfer length limit Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 04/87] drm/bridge: adv7511: Attach to DSI host at probe time Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 05/87] drm/kms: Catch mode_object lifetime errors Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 06/87] drm/vkms: Avoid assigning 0 for possible_crtc Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 07/87] drm/panel: simple: fix AUO g185han01 horizontal blanking Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 08/87] drm/amd/display: add monitor patch to add T7 delay Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 09/87] drm/amd/display: Power-gate all DSCs at driver init time Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 10/87] drm/amd/display: fix not calling ppsmu to trigger PME Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 11/87] drm/amd/display: Clear FEC_READY shadow register if DPCD write fails Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 12/87] drm/amd/display: Copy GSL groups when committing a new context Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 13/87] video: ssd1307fb: Start page range at page_offset Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 14/87] drm/tinydrm/Kconfig: drivers: Select BACKLIGHT_CLASS_DEVICE Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 15/87] drm/stm: attach gem fence to atomic state Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 16/87] drm/bridge: sii902x: fix missing reference to mclk clock Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 17/87] drm/panel: check failure cases in the probe func Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 18/87] drm/rockchip: Check for fast link training before enabling psr Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 19/87] drm/amdgpu: Fix hard hang for S/G display BOs Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 20/87] drm/amd/display: Use proper enum conversion functions Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 21/87] drm/radeon: Fix EEH during kexec Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 22/87] gpu: drm: radeon: Fix a possible null-pointer dereference in radeon_connector_set_property() Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 23/87] clk: imx8mq: Mark AHB clock as critical Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 24/87] PCI: rpaphp: Avoid a sometimes-uninitialized warning Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 25/87] pinctrl: stmfx: update pinconf settings Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 26/87] ipmi_si: Only schedule continuously in the thread in maintenance mode Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 27/87] clk: qoriq: Fix -Wunused-const-variable Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 28/87] clk: ingenic/jz4740: Fix "pll half" divider not read/written properly Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 29/87] clk: sunxi-ng: v3s: add missing clock slices for MMC2 module clocks Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 30/87] drm/amd/display: fix issue where 252-255 values are clipped Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 31/87] drm/amd/display: Fix frames_to_insert math Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 32/87] drm/amd/display: reprogram VM config when system resume Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 33/87] drm/amd/display: Register VUPDATE_NO_LOCK interrupts for DCN2 Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 34/87] powerpc/powernv/ioda2: Allocate TCE table levels on demand for default DMA window Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 35/87] drm/amd/powerplay/smu7: enforce minimal VBITimeout (v2) Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 36/87] clk: actions: Don't reference clk_init_data after registration Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 37/87] clk: sirf: " Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 38/87] clk: meson: axg-audio: " Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 39/87] clk: sprd: " Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 40/87] clk: zx296718: " Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 41/87] clk: sunxi: Don't call clk_hw_get_name() on a hw that isn't registered Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 42/87] powerpc/xmon: Check for HV mode when dumping XIVE info from OPAL Sasha Levin
2019-09-24 16:40 ` [PATCH AUTOSEL 5.3 43/87] powerpc/rtas: use device model APIs and serialization during LPM Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 44/87] powerpc/ptdump: fix walk_pagetables() address mismatch Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 45/87] powerpc/futex: Fix warning: 'oldval' may be used uninitialized in this function Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 46/87] powerpc/64s/radix: Remove redundant pfn_pte bitop, add VM_BUG_ON Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 47/87] powerpc/64s/radix: Fix memory hotplug section page table creation Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 48/87] powerpc/pseries/mobility: use cond_resched when updating device tree Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 49/87] powerpc/perf: fix imc allocation failure handling Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 50/87] pinctrl: tegra: Fix write barrier placement in pmx_writel Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 51/87] powerpc/eeh: Clear stale EEH_DEV_NO_HANDLER flag Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 52/87] vfio_pci: Restore original state on release Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 53/87] drm/amdgpu/sdma5: fix number of sdma5 trap irq types for navi1x Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 54/87] drm/nouveau/kms/tu102-: disable input lut when input is already FP16 Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 55/87] drm/nouveau/volt: Fix for some cards having 0 maximum voltage Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 56/87] pinctrl: amd: disable spurious-firing GPIO IRQs Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 57/87] clk: renesas: mstp: Set GENPD_FLAG_ALWAYS_ON for clock domain Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 58/87] clk: renesas: cpg-mssr: " Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 59/87] drm/amd/display: support spdif Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 60/87] drm/amd/powerpaly: fix navi series custom peak level value error Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 61/87] drm/amd/display: fix MPO HUBP underflow with Scatter Gather Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 62/87] drm/amd/display: fix trigger not generated for freesync Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 63/87] selftests/powerpc: Retry on host facility unavailable Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 64/87] kbuild: Do not enable -Wimplicit-fallthrough for clang for now Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 65/87] drm/amdgpu/si: fix ASIC tests Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 66/87] powerpc/64s/exception: machine check use correct cfar for late handler Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 67/87] pstore: fs superblock limits Sasha Levin
2019-09-24 16:41 ` Sasha Levin [this message]
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 69/87] powerpc/imc: Dont create debugfs files for cpu-less nodes Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 70/87] clk: qcom: gcc-sdm845: Use floor ops for sdcc clks Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 71/87] powerpc/pseries: correctly track irq state in default idle Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 72/87] pinctrl: meson-gxbb: Fix wrong pinning definition for uart_c Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 73/87] mailbox: mediatek: cmdq: clear the event in cmdq initial flow Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 74/87] ARM: dts: dir685: Drop spi-cpol from the display Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 75/87] arm64: fix unreachable code issue with cmpxchg Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 76/87] clk: at91: select parent if main oscillator or bypass is enabled Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 77/87] clk: imx: pll14xx: avoid glitch when set rate Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 78/87] clk: imx: clk-pll14xx: unbypass PLL by default Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 79/87] clk: Make clk_bulk_get_all() return a valid "id" Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 80/87] powerpc: dump kernel log before carrying out fadump or kdump Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 81/87] mbox: qcom: add APCS child device for QCS404 Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 82/87] clk: sprd: add missing kfree Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 83/87] scsi: core: Reduce memory required for SCSI logging Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 84/87] dma-buf/sw_sync: Synchronize signal vs syncpt free Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 85/87] drm: fix module name in edid_firmware log message Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 86/87] f2fs: fix to drop meta/node pages during umount Sasha Levin
2019-09-24 16:41 ` [PATCH AUTOSEL 5.3 87/87] ext4: fix potential use after free after remounting with noblock_validity Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190924164144.25591-68-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=mpe@ellerman.id.au \
--cc=oohall@gmail.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).