On Wed, Oct 13, 2021 at 12:26:42PM +0300, Andy Shevchenko wrote: > On Wed, Oct 13, 2021 at 2:33 AM Bjorn Helgaas <helgaas@xxxxxxxxxx> wrote: > > On Mon, Oct 04, 2021 at 02:59:24PM +0200, Uwe Kleine-König wrote: > > > I split some of the bigger patches apart so they only touched one > > driver or subsystem at a time. I also updated to_pci_driver() so it > > returns NULL when given NULL, which makes some of the validations > > quite a bit simpler, especially in the PM code in pci-driver.c. > > It's a bit unusual. Other to_*_dev() are not NULL-aware IIRC. It is a little unusual. I only found three of 77 that are NULL-aware: to_moxtet_driver() to_siox_driver() to_spi_driver() It seems worthwhile to me because it makes the patch and the resulting code significantly cleaner. Here's one example without the NULL check: @@ -493,12 +493,15 @@ static void pci_device_remove(struct device *dev) static void pci_device_shutdown(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct pci_driver *drv = pci_dev->driver; pm_runtime_resume(dev); - if (drv && drv->shutdown) - drv->shutdown(pci_dev); + if (pci_dev->dev.driver) { + struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver); + + if (drv->shutdown) + drv->shutdown(pci_dev); + } static void pci_device_shutdown(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); pm_runtime_resume(dev); if (pci_dev->dev.driver) { struct pci_driver *drv = to_pci_driver(pci_dev->dev.driver); if (drv->shutdown) drv->shutdown(pci_dev); } and here's the same thing with the NULL check: @@ -493,7 +493,7 @@ static void pci_device_remove(struct device *dev) static void pci_device_shutdown(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - struct pci_driver *drv = pci_dev->driver; + struct pci_driver *drv = to_pci_driver(dev->driver); static void pci_device_shutdown(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *drv = to_pci_driver(dev->driver); pm_runtime_resume(dev); if (drv && drv->shutdown) drv->shutdown(pci_dev); > > static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device) > > { > > + struct pci_driver *drv = to_pci_driver(pdev->dev.driver); > > const struct pci_device_id *id; > > > > if (pdev->vendor == vendor && pdev->device == device) > > return true; > > > + for (id = drv ? drv->id_table : NULL; id && id->vendor; id++) > > + if (id->vendor == vendor && id->device == device) > > > + break; > > return true; > > > return id && id->vendor; > > return false; Good cleanup for a follow-up patch, but doesn't seem directly related to the objective here. The current patch is: @@ -80,7 +80,7 @@ static struct resource video_rom_resource = { */ static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device) { - struct pci_driver *drv = pdev->driver; + struct pci_driver *drv = to_pci_driver(pdev->dev.driver); const struct pci_device_id *id; if (pdev->vendor == vendor && pdev->device == device) > > device_lock(&vf_dev->dev); > > - if (vf_dev->dev.driver) { > > + if (to_pci_driver(vf_dev->dev.driver)) { > > Hmm... Yeah, it could be either of: if (to_pci_driver(vf_dev->dev.driver)) if (vf_dev->dev.driver) I went back and forth on that and went with to_pci_driver() on the theory that we were testing the pci_driver * before and the patch is more of a mechanical change and easier to review if we test the pci_driver * after. > > + if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 > > > + && pci_dev->current_state != PCI_UNKNOWN) { > > Can we keep && on the previous line? I think this is in pci_legacy_suspend(), and I didn't touch that line. It shows up in the interdiff because without the NULL check in to_pci_driver(), we had to indent this code another level. With the NULL check, we don't need that extra indentation. > > + pci_WARN_ONCE(pci_dev, pci_dev->current_state != prev, > > + "PCI PM: Device state not saved by %pS\n", > > + drv->suspend); > > } > > ... > > > + return drv && drv->resume ? > > + drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev); > > One line? I don't think I touched that line. > > + struct pci_driver *drv = to_pci_driver(dev->dev.driver); > > const struct pci_error_handlers *err_handler = > > - dev->dev.driver ? to_pci_driver(dev->dev.driver)->err_handler : NULL; > > + drv ? drv->err_handler : NULL; > > Isn't dev->driver == to_pci_driver(dev->dev.driver)? Yes, I think so, but not sure what you're getting at here, can you elaborate? > > device_lock(&dev->dev); > > + pdrv = to_pci_driver(dev->dev.driver); > > if (!pci_dev_set_io_state(dev, state) || > > - !dev->dev.driver || > > - !(pdrv = to_pci_driver(dev->dev.driver))->err_handler || > > > + !pdrv || > > + !pdrv->err_handler || > > One line now? > > > !pdrv->err_handler->error_detected) { > > Or this and the previous line? Could, but the "dev->driver" to "to_pci_driver(dev->dev.driver)" changes are the heart of this patch, and I don't like to clutter it with unrelated changes. > > - result = PCI_ERS_RESULT_NONE; > > > > pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn); > > if (!pcidev || !pcidev->dev.driver) { > > dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n"); > > pci_dev_put(pcidev); > > - return result; > > + return PCI_ERS_RESULT_NONE; > > } > > pdrv = to_pci_driver(pcidev->dev.driver); > > What about splitting the conditional to two with clear error message > in each and use pci_err() in the second one? Could possibly be cleaned up. Felt like feature creep so I didn't. > > default: > > dev_err(&pdev->xdev->dev, > > - "bad request in aer recovery " > > - "operation!\n"); > > + "bad request in AER recovery operation!\n"); > > Stray change? Or is it in a separate patch in your tree? Could be skipped. The string now fits on one line so I combined it to make it more greppable. Bjorn