Message ID | 20201003075514.32935-4-haifeng.zhao@intel.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | Fix DPC hotplug race and enhance error handling | expand |
On Sat, Oct 03, 2020 at 03:55:12AM -0400, Ethan Zhao wrote: > When root port has DPC capability and it is enabled, then triggered by > errors, DPC DLLSC and PDC etc interrupts will be sent to DPC driver, pciehp > drivers almost at the same time. Do the DLLSC and PDC events occur as a result of handling the error or do they occur independently? If the latter, I don't see how we can tell whether the card in the slot is still the same. If the former, holding the hotplug slot's reset_lock and doing something along the lines of pciehp_reset_slot() (or calling it directly) might solve the race. Thanks, Lukas
Lukas, On Mon, Oct 5, 2020 at 3:13 AM Lukas Wunner <lukas@wunner.de> wrote: > > On Sat, Oct 03, 2020 at 03:55:12AM -0400, Ethan Zhao wrote: > > When root port has DPC capability and it is enabled, then triggered by > > errors, DPC DLLSC and PDC etc interrupts will be sent to DPC driver, pciehp > > drivers almost at the same time. > > Do the DLLSC and PDC events occur as a result of handling the error > or do they occur independently? They could happen independently if links were recovered then the card was removed. They could happen as a result of handling the errors the same time. So don't assume DLLSC and PDC all occur at the same time. > > If the latter, I don't see how we can tell whether the card in the > slot is still the same. If PDC happens, the card in the slot might not be the same. so hot-removal /hot -plugin handling follows the PDC event. > > If the former, holding the hotplug slot's reset_lock and doing something > along the lines of pciehp_reset_slot() (or calling it directly) might > solve the race. DPC reset is done by hardware, only AER calls pciehp_reset_slot() as recovery handling initiated by software. Thanks, Ethan > > Thanks, > > Lukas
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 53433b37e181..6f271160f18d 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -710,8 +710,10 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) down_read(&ctrl->reset_lock); if (events & DISABLE_SLOT) pciehp_handle_disable_request(ctrl); - else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) + else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) { + pci_wait_port_outdpc(pdev); pciehp_handle_presence_or_link_change(ctrl, events); + } up_read(&ctrl->reset_lock); ret = IRQ_HANDLED;