Re: [PATCH] pci: Only disable MSI/X and enable INTx if shutdown function has been called

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 03/09/2017 04:57 PM, Bjorn Helgaas wrote:
> Hi Prarit,
> 
> My abject apologies for taking so long to deal with this.

np.  It's only two lines but it is also complex code and I know you're busy.

>>  drivers/pci/pci-driver.c |    7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
>> index 1ccce1cd6aca..87c35db5a564 100644
>> --- a/drivers/pci/pci-driver.c
>> +++ b/drivers/pci/pci-driver.c
>> @@ -461,10 +461,11 @@ static void pci_device_shutdown(struct device *dev)
>>  
>>  	pm_runtime_resume(dev);
>>  
>> -	if (drv && drv->shutdown)
>> +	if (drv && drv->shutdown) {
>>  		drv->shutdown(pci_dev);
>> -	pci_msi_shutdown(pci_dev);
>> -	pci_msix_shutdown(pci_dev);
>> +		pci_msi_shutdown(pci_dev);
>> +		pci_msix_shutdown(pci_dev);
>> +	}
> 
> I love this patch because it cleans up pci_device_shutdown().  You
> mentioned that you've also tested a patch that just removes the calls
> to pci_msi_shutdown() and pci_msix_shutdown() completely.  I like that
> even more.
> 
> As Keith pointed out, the driver remains bound to the device even
> after we call pci_device_shutdown(), and the PCI core should not
> change the configuration of the device behind the back of the driver.
> 
> I think these commits are important pieces:
> 
>   1851617cd2da ("PCI/MSI: Disable MSI at enumeration even if kernel
>     doesn't support MSI")
>   e80e7edc55ba ("PCI/MSI: Initialize MSI capability for all
>     architectures")
> 
> because they ensure that a kexeced kernel can deal with MSIs being
> left enabled.
> 
> What do you think of the following two patches?  Thanks for all the
> details in your changelog -- I think they finally helped me gel all
> the pieces in my mind, and it all seems obvious now.  I tried to
> distill it down to just the critical pieces.
> 

I'm good with these two patches.

P.

> Bjorn
> 
> 
> commit fda78d7a0ead144f4b2cdb582dcba47911f4952c
> Author: Prarit Bhargava <prarit@xxxxxxxxxx>
> Date:   Thu Jan 26 14:07:47 2017 -0500
> 
>     PCI/MSI: Stop disabling MSI/MSI-X in pci_device_shutdown()
>     
>     The pci_bus_type .shutdown method, pci_device_shutdown(), is called from
>     device_shutdown() in the kernel restart and shutdown paths.
>     
>     Previously, pci_device_shutdown() called pci_msi_shutdown() and
>     pci_msix_shutdown().  This disables MSI and MSI-X, which causes the device
>     to fall back to raising interrupts via INTx.  But the driver is still bound
>     to the device, it doesn't know about this change, and it likely doesn't
>     have an INTx handler, so these INTx interrupts cause "nobody cared"
>     warnings like this:
>     
>       irq 16: nobody cared (try booting with the "irqpoll" option)
>       CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.2-1.el7_UNSUPPORTED.x86_64 #1
>       Hardware name: Hewlett-Packard HP Z820 Workstation/158B, BIOS J63 v03.90 06/
>       ...
>     
>     The MSI disabling code was added by d52877c7b1af ("pci/irq: let
>     pci_device_shutdown to call pci_msi_shutdown v2") because a driver left MSI
>     enabled and kdump failed because the kexeced kernel wasn't prepared to
>     receive the MSI interrupts.
>     
>     Subsequent commits 1851617cd2da ("PCI/MSI: Disable MSI at enumeration even
>     if kernel doesn't support MSI") and  e80e7edc55ba ("PCI/MSI: Initialize MSI
>     capability for all architectures") changed the kexeced kernel to disable
>     all MSIs itself so it no longer depends on the crashed kernel to clean up
>     after itself.
>     
>     Stop disabling MSI/MSI-X in pci_device_shutdown().  This resolves the
>     "nobody cared" unhandled IRQ issue above.  It also allows PCI serial
>     devices, which may rely on the MSI interrupts, to continue outputting
>     messages during reboot/shutdown.
>     
>     [bhelgaas: changelog, drop pci_msi_shutdown() and pci_msix_shutdown() calls
>     altogether]
>     Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=187351
>     Signed-off-by: Prarit Bhargava <prarit@xxxxxxxxxx>
>     Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
>     CC: Alex Williamson <alex.williamson@xxxxxxxxxx>
>     CC: David Arcari <darcari@xxxxxxxxxx>
>     CC: Myron Stowe <mstowe@xxxxxxxxxx>
>     CC: Lukas Wunner <lukas@xxxxxxxxx>
>     CC: Keith Busch <keith.busch@xxxxxxxxx>
>     CC: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx>
> 
> diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
> index afa72717a979..8ec136164e93 100644
> --- a/drivers/pci/pci-driver.c
> +++ b/drivers/pci/pci-driver.c
> @@ -461,8 +461,6 @@ static void pci_device_shutdown(struct device *dev)
>  
>  	if (drv && drv->shutdown)
>  		drv->shutdown(pci_dev);
> -	pci_msi_shutdown(pci_dev);
> -	pci_msix_shutdown(pci_dev);
>  
>  	/*
>  	 * If this is a kexec reboot, turn off Bus Master bit on the
> 
> commit 688769f643bfce894f14dc7141bfc6c010f52750
> Author: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
> Date:   Thu Mar 9 15:45:14 2017 -0600
> 
>     PCI/MSI: Make pci_msi_shutdown() and pci_msix_shutdown() static
>     
>     pci_msi_shutdown() and pci_msix_shutdown() are used only in
>     drivers/pci/msi.c, so make them static.
>     
>     Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
> 
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index d571bc330686..4d062c3bf5f0 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -882,7 +882,7 @@ int pci_msi_vec_count(struct pci_dev *dev)
>  }
>  EXPORT_SYMBOL(pci_msi_vec_count);
>  
> -void pci_msi_shutdown(struct pci_dev *dev)
> +static void pci_msi_shutdown(struct pci_dev *dev)
>  {
>  	struct msi_desc *desc;
>  	u32 mask;
> @@ -994,7 +994,7 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
>  }
>  EXPORT_SYMBOL(pci_enable_msix);
>  
> -void pci_msix_shutdown(struct pci_dev *dev)
> +static void pci_msix_shutdown(struct pci_dev *dev)
>  {
>  	struct msi_desc *entry;
>  
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index eb3da1a04e6c..10917c122974 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1297,11 +1297,9 @@ struct msix_entry {
>  
>  #ifdef CONFIG_PCI_MSI
>  int pci_msi_vec_count(struct pci_dev *dev);
> -void pci_msi_shutdown(struct pci_dev *dev);
>  void pci_disable_msi(struct pci_dev *dev);
>  int pci_msix_vec_count(struct pci_dev *dev);
>  int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec);
> -void pci_msix_shutdown(struct pci_dev *dev);
>  void pci_disable_msix(struct pci_dev *dev);
>  void pci_restore_msi_state(struct pci_dev *dev);
>  int pci_msi_enabled(void);
> @@ -1327,13 +1325,11 @@ int pci_irq_get_node(struct pci_dev *pdev, int vec);
>  
>  #else
>  static inline int pci_msi_vec_count(struct pci_dev *dev) { return -ENOSYS; }
> -static inline void pci_msi_shutdown(struct pci_dev *dev) { }
>  static inline void pci_disable_msi(struct pci_dev *dev) { }
>  static inline int pci_msix_vec_count(struct pci_dev *dev) { return -ENOSYS; }
>  static inline int pci_enable_msix(struct pci_dev *dev,
>  				  struct msix_entry *entries, int nvec)
>  { return -ENOSYS; }
> -static inline void pci_msix_shutdown(struct pci_dev *dev) { }
>  static inline void pci_disable_msix(struct pci_dev *dev) { }
>  static inline void pci_restore_msi_state(struct pci_dev *dev) { }
>  static inline int pci_msi_enabled(void) { return 0; }
> 



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux