s390/pci: fix leak of PCI device structure
In commit05bc1be6db("s390/pci: create zPCI bus") we removed the pci_dev_put() call matching the earlier pci_get_slot() done as part of __zpci_event_availability(). This was based on the wrong understanding that the device_put() done as part of pci_destroy_device() would counter the pci_get_slot() when it only counters the initial reference. This same understanding and existing bad example also lead to not doing a pci_dev_put() in zpci_remove_device(). Since releasing the PCI devices, unlike releasing the PCI slot, does not print any debug message for testing I added one in pci_release_dev(). This revealed that we are indeed leaking the PCI device on PCI hotunplug. Further testing also revealed another missing pci_dev_put() in disable_slot(). Fix this by adding the missing pci_dev_put() in disable_slot() and fix zpci_remove_device() with the correct pci_dev_put() calls. Also instead of calling pci_get_slot() in __zpci_event_availability() to determine if a PCI device is registered and then doing the same again in zpci_remove_device() do this once in zpci_remove_device() which makes sure that the pdev in __zpci_event_availability() is only used for the result of pci_scan_single_device() which does not need a reference count decremnt as its ownership goes to the PCI bus. Also move the check if zdev->zbus->bus is set into zpci_remove_device() since it may be that we're removing a device with devfn != 0 which never had a PCI bus. So we can still set the pdev->error_state to indicate that the device is not usable anymore, add a flag to set the error state. Fixes:05bc1be6db("s390/pci: create zPCI bus") Cc: <stable@vger.kernel.org> # 5.8+:e1bff843cds390/pci: remove superfluous zdev->zbus check Cc: <stable@vger.kernel.org> # 5.8+:ba764dd703s390/pci: refactor zpci_create_device() Cc: <stable@vger.kernel.org> # 5.8+ Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
committed by
Heiko Carstens
parent
d54cb7d548
commit
0b13525c20
@@ -202,7 +202,7 @@ extern unsigned int s390_pci_no_rid;
|
||||
----------------------------------------------------------------------------- */
|
||||
/* Base stuff */
|
||||
int zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
|
||||
void zpci_remove_device(struct zpci_dev *zdev);
|
||||
void zpci_remove_device(struct zpci_dev *zdev, bool set_error);
|
||||
int zpci_enable_device(struct zpci_dev *);
|
||||
int zpci_disable_device(struct zpci_dev *);
|
||||
int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
|
||||
|
||||
Reference in New Issue
Block a user