From 477c42682de9201ee21d21709a635e619a1b53d1 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Aug 05 2020 12:59:08 +0000 Subject: Merge remote-tracking branch 'origin/users/tiwai/SLE15-SP1/EMU' into users/dkirjanov/SLE12-SP5/EMU --- diff --git a/patches.suse/0001-PCI-pciehp-Avoid-returning-prematurely-from-sysfs-re.patch b/patches.suse/0001-PCI-pciehp-Avoid-returning-prematurely-from-sysfs-re.patch index ac710d7..1254c70 100644 --- a/patches.suse/0001-PCI-pciehp-Avoid-returning-prematurely-from-sysfs-re.patch +++ b/patches.suse/0001-PCI-pciehp-Avoid-returning-prematurely-from-sysfs-re.patch @@ -75,7 +75,7 @@ Signed-off-by: Oliver Neukum case POWEROFF_STATE: --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -443,6 +443,7 @@ int pciehp_set_raw_indicator_status(stru +@@ -442,6 +442,7 @@ int pciehp_set_raw_indicator_status(stru struct controller *ctrl = hotplug_slot->private; struct pci_dev *pdev = ctrl_dev(ctrl); @@ -83,10 +83,10 @@ Signed-off-by: Oliver Neukum pci_config_pm_runtime_get(pdev); pcie_write_cmd_nowait(ctrl, status << 6, PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC); -@@ -686,6 +687,7 @@ static irqreturn_t pciehp_ist(int irq, v +@@ -645,6 +646,7 @@ static irqreturn_t pciehp_ist(int irq, v + pciehp_handle_presence_or_link_change(ctrl, events); up_read(&ctrl->reset_lock); - pci_config_pm_runtime_put(pdev); + ctrl->ist_running = false; wake_up(&ctrl->requester); return IRQ_HANDLED; diff --git a/patches.suse/0001-PCI-pciehp-Do-not-handle-events-if-interrupts-are-ma.patch b/patches.suse/0001-PCI-pciehp-Do-not-handle-events-if-interrupts-are-ma.patch index e13cbd7..df6347f 100644 --- a/patches.suse/0001-PCI-pciehp-Do-not-handle-events-if-interrupts-are-ma.patch +++ b/patches.suse/0001-PCI-pciehp-Do-not-handle-events-if-interrupts-are-ma.patch @@ -23,7 +23,7 @@ Signed-off-by: Oliver Neukum --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -552,9 +552,11 @@ static irqreturn_t pciehp_isr(int irq, v +@@ -562,9 +562,11 @@ static irqreturn_t pciehp_isr(int irq, v u16 status, events; /* @@ -36,4 +36,4 @@ Signed-off-by: Oliver Neukum + (!(ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE) && !pciehp_poll_mode)) return IRQ_NONE; - /* + pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); diff --git a/patches.suse/0001-PCI-pciehp-Fix-hot-add-vs-powerfault-detection-order.patch b/patches.suse/0001-PCI-pciehp-Fix-hot-add-vs-powerfault-detection-order.patch index 0b3e48d..b22ac88 100644 --- a/patches.suse/0001-PCI-pciehp-Fix-hot-add-vs-powerfault-detection-order.patch +++ b/patches.suse/0001-PCI-pciehp-Fix-hot-add-vs-powerfault-detection-order.patch @@ -52,7 +52,7 @@ Signed-off-by: Oliver Neukum --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -511,7 +511,7 @@ int pciehp_power_on_slot(struct slot *sl +@@ -510,7 +510,7 @@ int pciehp_power_on_slot(struct slot *sl u16 slot_status; int retval; @@ -61,7 +61,7 @@ Signed-off-by: Oliver Neukum pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); if (slot_status & PCI_EXP_SLTSTA_PFD) pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, -@@ -661,6 +661,14 @@ static irqreturn_t pciehp_ist(int irq, v +@@ -621,6 +621,14 @@ static irqreturn_t pciehp_ist(int irq, v pciehp_handle_button_press(slot); } @@ -76,7 +76,7 @@ Signed-off-by: Oliver Neukum /* * Disable requests have higher priority than Presence Detect Changed * or Data Link Layer State Changed events. -@@ -672,14 +680,6 @@ static irqreturn_t pciehp_ist(int irq, v +@@ -632,14 +640,6 @@ static irqreturn_t pciehp_ist(int irq, v pciehp_handle_presence_or_link_change(slot, events); up_read(&ctrl->reset_lock); @@ -88,6 +88,6 @@ Signed-off-by: Oliver Neukum - pciehp_green_led_off(slot); - } - - pci_config_pm_runtime_put(pdev); wake_up(&ctrl->requester); return IRQ_HANDLED; + } diff --git a/patches.suse/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch b/patches.suse/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch index 50fbd2d..5b141a2 100644 --- a/patches.suse/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch +++ b/patches.suse/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch @@ -96,7 +96,7 @@ Signed-off-by: Oliver Neukum int request_result; wait_queue_head_t requester; }; -@@ -190,28 +168,28 @@ struct controller { +@@ -185,28 +163,28 @@ struct controller { #define PSN(ctrl) (((ctrl)->slot_cap & PCI_EXP_SLTCAP_PSN) >> 19) void pciehp_request(struct controller *ctrl, int action); @@ -142,7 +142,7 @@ Signed-off-by: Oliver Neukum bool pciehp_card_present(struct controller *ctrl); bool pciehp_card_present_or_link_active(struct controller *ctrl); int pciehp_check_link_status(struct controller *ctrl); -@@ -225,9 +203,9 @@ int pciehp_get_attention_status(struct h +@@ -220,9 +198,9 @@ int pciehp_get_attention_status(struct h int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status); int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status); @@ -833,7 +833,7 @@ Signed-off-by: Oliver Neukum } --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -58,7 +58,7 @@ static inline int pciehp_request_irq(str +@@ -57,7 +57,7 @@ static inline int pciehp_request_irq(str if (pciehp_poll_mode) { ctrl->poll_thread = kthread_run(&pciehp_poll, ctrl, "pciehp_poll-%s", @@ -842,7 +842,7 @@ Signed-off-by: Oliver Neukum return PTR_ERR_OR_ZERO(ctrl->poll_thread); } -@@ -333,8 +333,8 @@ static int pciehp_link_enable(struct con +@@ -332,8 +332,8 @@ static int pciehp_link_enable(struct con int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 *status) { @@ -853,7 +853,7 @@ Signed-off-by: Oliver Neukum u16 slot_ctrl; pci_config_pm_runtime_get(pdev); -@@ -346,8 +346,7 @@ int pciehp_get_raw_indicator_status(stru +@@ -345,8 +345,7 @@ int pciehp_get_raw_indicator_status(stru int pciehp_get_attention_status(struct hotplug_slot *hotplug_slot, u8 *status) { @@ -863,7 +863,7 @@ Signed-off-by: Oliver Neukum struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_ctrl; -@@ -375,9 +374,8 @@ int pciehp_get_attention_status(struct h +@@ -374,9 +373,8 @@ int pciehp_get_attention_status(struct h return 0; } @@ -874,7 +874,7 @@ Signed-off-by: Oliver Neukum struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_ctrl; -@@ -398,9 +396,9 @@ void pciehp_get_power_status(struct slot +@@ -397,9 +395,9 @@ void pciehp_get_power_status(struct slot } } @@ -886,7 +886,7 @@ Signed-off-by: Oliver Neukum u16 slot_status; pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); -@@ -430,9 +428,9 @@ bool pciehp_card_present_or_link_active( +@@ -429,9 +427,9 @@ bool pciehp_card_present_or_link_active( return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl); } @@ -898,7 +898,7 @@ Signed-off-by: Oliver Neukum u16 slot_status; pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); -@@ -442,8 +440,7 @@ int pciehp_query_power_fault(struct slot +@@ -441,8 +439,7 @@ int pciehp_query_power_fault(struct slot int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 status) { @@ -908,7 +908,7 @@ Signed-off-by: Oliver Neukum struct pci_dev *pdev = ctrl_dev(ctrl); pci_config_pm_runtime_get(pdev); -@@ -453,9 +450,8 @@ int pciehp_set_raw_indicator_status(stru +@@ -452,9 +449,8 @@ int pciehp_set_raw_indicator_status(stru return 0; } @@ -919,7 +919,7 @@ Signed-off-by: Oliver Neukum u16 slot_cmd; if (!ATTN_LED(ctrl)) -@@ -479,10 +475,8 @@ void pciehp_set_attention_status(struct +@@ -478,10 +474,8 @@ void pciehp_set_attention_status(struct pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); } @@ -931,7 +931,7 @@ Signed-off-by: Oliver Neukum if (!PWR_LED(ctrl)) return; -@@ -493,10 +487,8 @@ void pciehp_green_led_on(struct slot *sl +@@ -492,10 +486,8 @@ void pciehp_green_led_on(struct slot *sl PCI_EXP_SLTCTL_PWR_IND_ON); } @@ -943,7 +943,7 @@ Signed-off-by: Oliver Neukum if (!PWR_LED(ctrl)) return; -@@ -507,10 +499,8 @@ void pciehp_green_led_off(struct slot *s +@@ -506,10 +498,8 @@ void pciehp_green_led_off(struct slot *s PCI_EXP_SLTCTL_PWR_IND_OFF); } @@ -955,7 +955,7 @@ Signed-off-by: Oliver Neukum if (!PWR_LED(ctrl)) return; -@@ -521,9 +511,8 @@ void pciehp_green_led_blink(struct slot +@@ -520,9 +510,8 @@ void pciehp_green_led_blink(struct slot PCI_EXP_SLTCTL_PWR_IND_BLINK); } @@ -966,7 +966,7 @@ Signed-off-by: Oliver Neukum struct pci_dev *pdev = ctrl_dev(ctrl); u16 slot_status; int retval; -@@ -547,10 +536,8 @@ int pciehp_power_on_slot(struct slot *sl +@@ -546,10 +535,8 @@ int pciehp_power_on_slot(struct slot *sl return retval; } @@ -978,15 +978,15 @@ Signed-off-by: Oliver Neukum pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC); ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, -@@ -648,7 +635,6 @@ static irqreturn_t pciehp_ist(int irq, v +@@ -623,7 +610,6 @@ static irqreturn_t pciehp_isr(int irq, v + static irqreturn_t pciehp_ist(int irq, void *dev_id) { struct controller *ctrl = (struct controller *)dev_id; - struct pci_dev *pdev = ctrl_dev(ctrl); - struct slot *slot = ctrl->slot; - irqreturn_t ret; u32 events; -@@ -674,16 +660,16 @@ static irqreturn_t pciehp_ist(int irq, v + synchronize_hardirq(irq); +@@ -634,16 +620,16 @@ static irqreturn_t pciehp_ist(int irq, v /* Check Attention Button Pressed */ if (events & PCI_EXP_SLTSTA_ABP) { ctrl_info(ctrl, "Slot(%s): Attention button pressed\n", @@ -1008,7 +1008,7 @@ Signed-off-by: Oliver Neukum } /* -@@ -692,9 +678,9 @@ static irqreturn_t pciehp_ist(int irq, v +@@ -652,9 +638,9 @@ static irqreturn_t pciehp_ist(int irq, v */ down_read(&ctrl->reset_lock); if (events & DISABLE_SLOT) @@ -1019,8 +1019,8 @@ Signed-off-by: Oliver Neukum + pciehp_handle_presence_or_link_change(ctrl, events); up_read(&ctrl->reset_lock); - pci_config_pm_runtime_put(pdev); -@@ -790,8 +776,7 @@ void pcie_clear_hotplug_events(struct co + wake_up(&ctrl->requester); +@@ -749,8 +735,7 @@ void pcie_clear_hotplug_events(struct co */ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe) { @@ -1030,7 +1030,7 @@ Signed-off-by: Oliver Neukum struct pci_dev *pdev = ctrl_dev(ctrl); u16 stat_mask = 0, ctrl_mask = 0; int rc; -@@ -841,42 +826,6 @@ void pcie_shutdown_notification(struct c +@@ -800,42 +785,6 @@ void pcie_shutdown_notification(struct c } } @@ -1073,7 +1073,7 @@ Signed-off-by: Oliver Neukum static inline void dbg_ctrl(struct controller *ctrl) { struct pci_dev *pdev = ctrl->pcie->port; -@@ -900,10 +849,11 @@ struct controller *pcie_init(struct pcie +@@ -859,10 +808,11 @@ struct controller *pcie_init(struct pcie u32 slot_cap, link_cap; u8 poweron; struct pci_dev *pdev = dev->port; @@ -1086,7 +1086,7 @@ Signed-off-by: Oliver Neukum ctrl->pcie = dev; pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); -@@ -920,11 +870,17 @@ struct controller *pcie_init(struct pcie +@@ -879,11 +829,17 @@ struct controller *pcie_init(struct pcie ctrl->slot_cap = slot_cap; mutex_init(&ctrl->ctrl_lock); @@ -1104,7 +1104,7 @@ Signed-off-by: Oliver Neukum /* Check if Data Link Layer Link Active Reporting is implemented */ pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap); if (link_cap & PCI_EXP_LNKCAP_DLLLARC) -@@ -950,32 +906,24 @@ struct controller *pcie_init(struct pcie +@@ -909,32 +865,24 @@ struct controller *pcie_init(struct pcie FLAG(link_cap, PCI_EXP_LNKCAP_DLLLARC), pdev->broken_cmd_compl ? " (with Cmd Compl erratum)" : ""); diff --git a/patches.suse/PCI-pciehp-Fix-indefinite-wait-on-sysfs-requests.patch b/patches.suse/PCI-pciehp-Fix-indefinite-wait-on-sysfs-requests.patch deleted file mode 100644 index e85c8ac..0000000 --- a/patches.suse/PCI-pciehp-Fix-indefinite-wait-on-sysfs-requests.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 3e487d2e4aa466decd226353755c9d423e8fbacc Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Wed, 18 Mar 2020 12:33:12 +0100 -Subject: [PATCH] PCI: pciehp: Fix indefinite wait on sysfs requests -Git-commit: 3e487d2e4aa466decd226353755c9d423e8fbacc -References: git-fixes -Patch-mainline: v5.7-rc1 - -David Hoyer reports that powering pciehp slots up or down via sysfs may -hang: The call to wait_event() in pciehp_sysfs_enable_slot() and -_disable_slot() does not return because ctrl->ist_running remains true. - -This flag, which was introduced by commit 157c1062fcd8 ("PCI: pciehp: Avoid -returning prematurely from sysfs requests"), signifies that the IRQ thread -pciehp_ist() is running. It is set to true at the top of pciehp_ist() and -reset to false at the end. However there are two additional return -statements in pciehp_ist() before which the commit neglected to reset the -flag to false and wake up waiters for the flag. - -That omission opens up the following race when powering up the slot: - -* pciehp_ist() runs because a PCI_EXP_SLTSTA_PDC event was requested - by pciehp_sysfs_enable_slot() - -* pciehp_ist() turns on slot power via the following call stack: - pciehp_handle_presence_or_link_change() -> pciehp_enable_slot() -> - __pciehp_enable_slot() -> board_added() -> pciehp_power_on_slot() - -* after slot power is turned on, the link comes up, resulting in a - PCI_EXP_SLTSTA_DLLSC event - -* the IRQ handler pciehp_isr() stores the event in ctrl->pending_events - and returns IRQ_WAKE_THREAD - -* the IRQ thread is already woken (it's bringing up the slot), but the - genirq code remembers to re-run the IRQ thread after it has finished - (such that it can deal with the new event) by setting IRQTF_RUNTHREAD - via __handle_irq_event_percpu() -> __irq_wake_thread() - -* the IRQ thread removes PCI_EXP_SLTSTA_DLLSC from ctrl->pending_events - via board_added() -> pciehp_check_link_status() in order to deal with - presence and link flaps per commit 6c35a1ac3da6 ("PCI: pciehp: - Tolerate initially unstable link") - -* after pciehp_ist() has successfully brought up the slot, it resets - ctrl->ist_running to false and wakes up the sysfs requester - -* the genirq code re-runs pciehp_ist(), which sets ctrl->ist_running - to true but then returns with IRQ_NONE because ctrl->pending_events - is empty - -* pciehp_sysfs_enable_slot() is finally woken but notices that - ctrl->ist_running is true, hence continues waiting - -The only way to get the hung task going again is to trigger a hotplug -event which brings down the slot, e.g. by yanking out the card. - -The same race exists when powering down the slot because remove_board() -likewise clears link or presence changes in ctrl->pending_events per commit -3943af9d01e9 ("PCI: pciehp: Ignore Link State Changes after powering off a -slot") and thereby may cause a re-run of pciehp_ist() which returns with -IRQ_NONE without resetting ctrl->ist_running to false. - -Fix by adding a goto label before the teardown steps at the end of -pciehp_ist() and jumping to that label from the two return statements which -currently neglect to reset the ctrl->ist_running flag. - -Fixes: 157c1062fcd8 ("PCI: pciehp: Avoid returning prematurely from sysfs requests") -Link: https://lore.kernel.org/r/cca1effa488065cb055120aa01b65719094bdcb5.1584530321.git.lukas@wunner.de -Reported-by: David Hoyer -Signed-off-by: Lukas Wunner -Signed-off-by: Bjorn Helgaas -Reviewed-by: Keith Busch -Cc: stable@vger.kernel.org # v4.19+ -Signed-off-by: Oliver Neukum ---- - drivers/pci/hotplug/pciehp_hpc.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c -index e4627c68b30f..5f1a27bfcb19 100644 ---- a/drivers/pci/hotplug/pciehp_hpc.c -+++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -663,17 +663,15 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) - if (atomic_fetch_and(~RERUN_ISR, &ctrl->pending_events) & RERUN_ISR) { - ret = pciehp_isr(irq, dev_id); - enable_irq(irq); -- if (ret != IRQ_WAKE_THREAD) { -- pci_config_pm_runtime_put(pdev); -- return ret; -- } -+ if (ret != IRQ_WAKE_THREAD) -+ goto out; - } - - synchronize_hardirq(irq); - events = atomic_xchg(&ctrl->pending_events, 0); - if (!events) { -- pci_config_pm_runtime_put(pdev); -- return IRQ_NONE; -+ ret = IRQ_NONE; -+ goto out; - } - - /* Check Attention Button Pressed */ -@@ -702,10 +700,12 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) - pciehp_handle_presence_or_link_change(ctrl, events); - up_read(&ctrl->reset_lock); - -+ ret = IRQ_HANDLED; -+out: - pci_config_pm_runtime_put(pdev); - ctrl->ist_running = false; - wake_up(&ctrl->requester); -- return IRQ_HANDLED; -+ return ret; - } - - static int pciehp_poll(void *data) --- -2.16.4 - diff --git a/patches.suse/PCI-pciehp-Support-interrupts-sent-from-D3hot.patch b/patches.suse/PCI-pciehp-Support-interrupts-sent-from-D3hot.patch deleted file mode 100644 index 872fab7..0000000 --- a/patches.suse/PCI-pciehp-Support-interrupts-sent-from-D3hot.patch +++ /dev/null @@ -1,203 +0,0 @@ -From 6b08c3854cfdc5d13165880e2b54642c47edc405 Mon Sep 17 00:00:00 2001 -From: Lukas Wunner -Date: Sat, 28 Jul 2018 07:18:00 +0200 -Subject: [PATCH] PCI: pciehp: Support interrupts sent from D3hot -Git-commit: 6b08c3854cfdc5d13165880e2b54642c47edc405 -References: git-fixes -Patch-mainline: v4.19-rc1 - -If a hotplug port is able to send an interrupt, one would naively assume -that it is accessible at that moment. After all, if it wouldn't be -accessible, i.e. if its parent is in D3hot and the link to the hotplug -port is thus down, how should an interrupt come through? - -It turns out that assumption is wrong at least for Thunderbolt: Even -though its parents are in D3hot, a Thunderbolt hotplug port is able to -signal interrupts. Because the port's config space is inaccessible and -resuming the parents may sleep, the hard IRQ handler has to defer -runtime resuming the parents and reading the Slot Status register to the -IRQ thread. - -If the hotplug port uses a level-triggered INTx interrupt, it needs to -be masked until the IRQ thread has cleared the signaled events. For -simplicity, this commit also masks edge-triggered MSI/MSI-X interrupts. -Note that if the interrupt is shared (which can only happen for INTx), -other devices are starved from receiving interrupts until the IRQ thread -is scheduled, has runtime resumed the hotplug port's parents and has -read and cleared the Slot Status register. - -That delay is dominated by the 10 ms D3hot->D0 transition time of each -parent port. The worst case is a Thunderbolt downstream port at the -end of a daisy chain: There may be up to six Thunderbolt controllers -in-between it and the root port, each comprising an upstream and -downstream port, plus its own upstream port. That's 13 x 10 = 130 ms. -Possible mitigations are polling the interrupt while it's disabled or -reducing the d3_delay of Thunderbolt ports if possible. - -Open code masking of the interrupt instead of requesting it with the -IRQF_ONESHOT flag to minimize the period during which it is masked. -(IRQF_ONESHOT unmasks the IRQ only after the IRQ thread has finished.) - -PCIe r4.0 sec 6.7.3.4 states that "If wake generation is required by the -associated form factor specification, a hotplug capable Downstream Port -must support generation of a wakeup event (using the PME mechanism) on -hotplug events that occur when the system is in a sleep state or the -Port is in device state D1, D2, or D3Hot." - -This would seem to imply that PME needs to be enabled on the hotplug -port when it is runtime suspended. pci_enable_wake() currently doesn't -enable PME on bridges, it may be necessary to add an exemption for -hotplug bridges there. On "Light Ridge" Thunderbolt controllers, the -PME_Status bit is not set when an interrupt occurs while the hotplug -port is in D3hot, even if PME is enabled. (I've tested this on a Mac -and we hardcode the OSC_PCI_EXPRESS_PME_CONTROL bit to 0 on Macs in -negotiate_os_control(), modifying it to 1 didn't change the behavior.) - -(Side note: Section 6.7.3.4 also states that "PME and Hot-Plug Event -interrupts (when both are implemented) always share the same MSI or -MSI-X vector". That would only seem to apply to Root Ports, however -the section never mentions Root Ports, only Downstream Ports. This is -explained in the definition of "Downstream Port" in the "Terms and -Acronyms" section of the PCIe Base Spec: "The Ports on a Switch that -are not the Upstream Port are Downstream Ports. All Ports on a Root -Complex are Downstream Ports.") - -Signed-off-by: Lukas Wunner -Signed-off-by: Bjorn Helgaas -Cc: Thomas Gleixner -Cc: Rafael J. Wysocki -Cc: Mika Westerberg -Cc: Ashok Raj -Cc: Keith Busch -Cc: Yinghai Lu -Signed-off-by: Oliver Neukum ---- - drivers/pci/hotplug/pciehp.h | 5 +++++ - drivers/pci/hotplug/pciehp_hpc.c | 45 ++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 48 insertions(+), 2 deletions(-) - -diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h -index 247681963063..811cf83f956d 100644 ---- a/drivers/pci/hotplug/pciehp.h -+++ b/drivers/pci/hotplug/pciehp.h -@@ -156,8 +156,13 @@ struct controller { - * - * %DISABLE_SLOT: Disable the slot in response to a user request via sysfs or - * an Attention Button press after the 5 second delay -+ * %RERUN_ISR: Used by the IRQ handler to inform the IRQ thread that the -+ * hotplug port was inaccessible when the interrupt occurred, requiring -+ * that the IRQ handler is rerun by the IRQ thread after it has made the -+ * hotplug port accessible by runtime resuming its parents to D0 - */ - #define DISABLE_SLOT (1 << 16) -+#define RERUN_ISR (1 << 17) - - #define ATTN_BUTTN(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_ABP) - #define POWER_CTRL(ctrl) ((ctrl)->slot_cap & PCI_EXP_SLTCAP_PCP) -diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c -index 6313ddf38a51..6e9b4330ad82 100644 ---- a/drivers/pci/hotplug/pciehp_hpc.c -+++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -521,6 +522,7 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) - { - struct controller *ctrl = (struct controller *)dev_id; - struct pci_dev *pdev = ctrl_dev(ctrl); -+ struct device *parent = pdev->dev.parent; - u16 status, events; - - /* -@@ -529,9 +531,26 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) - if (pdev->current_state == PCI_D3cold) - return IRQ_NONE; - -+ /* -+ * Keep the port accessible by holding a runtime PM ref on its parent. -+ * Defer resume of the parent to the IRQ thread if it's suspended. -+ * Mask the interrupt until then. -+ */ -+ if (parent) { -+ pm_runtime_get_noresume(parent); -+ if (!pm_runtime_active(parent)) { -+ pm_runtime_put(parent); -+ disable_irq_nosync(irq); -+ atomic_or(RERUN_ISR, &ctrl->pending_events); -+ return IRQ_WAKE_THREAD; -+ } -+ } -+ - pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); - if (status == (u16) ~0) { - ctrl_info(ctrl, "%s: no response from device\n", __func__); -+ if (parent) -+ pm_runtime_put(parent); - return IRQ_NONE; - } - -@@ -550,11 +569,16 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) - if (ctrl->power_fault_detected) - events &= ~PCI_EXP_SLTSTA_PFD; - -- if (!events) -+ if (!events) { -+ if (parent) -+ pm_runtime_put(parent); - return IRQ_NONE; -+ } - - pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); - ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); -+ if (parent) -+ pm_runtime_put(parent); - - /* - * Command Completed notifications are not deferred to the -@@ -584,13 +608,29 @@ static irqreturn_t pciehp_isr(int irq, void *dev_id) - static irqreturn_t pciehp_ist(int irq, void *dev_id) - { - struct controller *ctrl = (struct controller *)dev_id; -+ struct pci_dev *pdev = ctrl_dev(ctrl); - struct slot *slot = ctrl->slot; -+ irqreturn_t ret; - u32 events; - -+ pci_config_pm_runtime_get(pdev); -+ -+ /* rerun pciehp_isr() if the port was inaccessible on interrupt */ -+ if (atomic_fetch_and(~RERUN_ISR, &ctrl->pending_events) & RERUN_ISR) { -+ ret = pciehp_isr(irq, dev_id); -+ enable_irq(irq); -+ if (ret != IRQ_WAKE_THREAD) { -+ pci_config_pm_runtime_put(pdev); -+ return ret; -+ } -+ } -+ - synchronize_hardirq(irq); - events = atomic_xchg(&ctrl->pending_events, 0); -- if (!events) -+ if (!events) { -+ pci_config_pm_runtime_put(pdev); - return IRQ_NONE; -+ } - - /* Check Attention Button Pressed */ - if (events & PCI_EXP_SLTSTA_ABP) { -@@ -618,6 +658,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) - pciehp_green_led_off(slot); - } - -+ pci_config_pm_runtime_put(pdev); - wake_up(&ctrl->requester); - return IRQ_HANDLED; - } --- -2.16.4 - diff --git a/patches.suse/pci-pciehp-fix-msi-interrupt-race b/patches.suse/pci-pciehp-fix-msi-interrupt-race index 93ea077..bc20101 100644 --- a/patches.suse/pci-pciehp-fix-msi-interrupt-race +++ b/patches.suse/pci-pciehp-fix-msi-interrupt-race @@ -41,36 +41,36 @@ Signed-off-by: Bjorn Helgaas Reviewed-by: Joerg Roedel Acked-by: Joerg Roedel --- - drivers/pci/hotplug/pciehp_hpc.c | 26 ++++++++++++++++++++------ + drivers/pci/hotplug/pciehp_hpc.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c -@@ -550,7 +550,7 @@ static irqreturn_t pciehp_isr(int irq, v +@@ -565,7 +565,7 @@ static irqreturn_t pciehp_isr(int irq, v + { struct controller *ctrl = (struct controller *)dev_id; struct pci_dev *pdev = ctrl_dev(ctrl); - struct device *parent = pdev->dev.parent; - u16 status, events; + u16 status, events = 0; /* * Interrupts only occur in D3hot or shallower and only if enabled -@@ -575,6 +575,7 @@ static irqreturn_t pciehp_isr(int irq, v - } - } +@@ -573,6 +573,7 @@ static irqreturn_t pciehp_isr(int irq, v + (!(ctrl->slot_ctrl & PCI_EXP_SLTCTL_HPIE) && !pciehp_poll_mode)) + return IRQ_NONE; +read_status: pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &status); if (status == (u16) ~0) { ctrl_info(ctrl, "%s: no response from device\n", __func__); -@@ -587,24 +588,37 @@ static irqreturn_t pciehp_isr(int irq, v +@@ -583,21 +584,34 @@ static irqreturn_t pciehp_isr(int irq, v * Slot Status contains plain status bits as well as event * notification bits; right now we only want the event bits. */ - events = status & (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | - PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | - PCI_EXP_SLTSTA_DLLSC); -+ events &= PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | ++ status &= PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD | + PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_CC | + PCI_EXP_SLTSTA_DLLSC; @@ -83,11 +83,8 @@ Acked-by: Joerg Roedel + status &= ~PCI_EXP_SLTSTA_PFD; + events |= status; - if (!events) { - if (parent) - pm_runtime_put(parent); + if (!events) return IRQ_NONE; - } - pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, events); + if (status) { @@ -104,5 +101,5 @@ Acked-by: Joerg Roedel + } + ctrl_dbg(ctrl, "pending interrupts %#06x from Slot Status\n", events); - if (parent) - pm_runtime_put(parent); + + /* diff --git a/series.conf b/series.conf index 18bfb10..b8d4987 100644 --- a/series.conf +++ b/series.conf @@ -39011,7 +39011,6 @@ patches.suse/0001-PCI-portdrv-Deduplicate-PM-callback-iterator.patch patches.suse/0001-PCI-pciehp-Clear-spurious-events-earlier-on-resume.patch patches.suse/PCI-pciehp-Obey-compulsory-command-delay-after-resum.patch - patches.suse/PCI-pciehp-Support-interrupts-sent-from-D3hot.patch patches.suse/0001-PCI-pciehp-Resume-parent-to-D0-on-config-space-acces.patch patches.suse/0001-PCI-pciehp-Deduplicate-presence-check-on-probe-resum.patch patches.suse/PCI-Mark-fall-through-switch-cases-before-enabling-W.patch @@ -54106,7 +54105,6 @@ patches.suse/x86-xen-make-the-secondary-cpu-idle-tasks-reliable.patch patches.suse/0019-coresight-do-not-use-the-BIT-macro-in-the-UAPI-heade.patch patches.suse/PCI-ASPM-Clear-the-correct-bits-when-enabling-L1-sub.patch - patches.suse/PCI-pciehp-Fix-indefinite-wait-on-sysfs-requests.patch patches.suse/pci-pciehp-fix-msi-interrupt-race patches.suse/PCI-endpoint-Fix-clearing-start-entry-in-configfs.patch patches.suse/misc-pci_endpoint_test-Fix-to-support-10-pci-endpoin.patch