Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Fix reference counting bug

pci_get_subsys() will decrement the reference count of the device that
it starts searching from. Unfortunately, the pci_find_device() interface
will already have decremented the reference count of the device earlier,
so the device will end up losing all reference counts and be freed.

We can fix this by incrementing the reference count of the device to
start searching from before calling pci_get_subsys().

Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

authored by

Matthew Wilcox and committed by
Jesse Barnes
c4ed02fa d389fec6

+3 -6
+3 -6
drivers/pci/search.c
··· 166 166 { 167 167 struct pci_dev *pdev; 168 168 169 + pci_dev_get(from); 169 170 pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from); 170 171 pci_dev_put(pdev); 171 172 return pdev; ··· 271 270 struct pci_dev *pdev = NULL; 272 271 273 272 WARN_ON(in_interrupt()); 274 - if (from) { 275 - /* FIXME 276 - * take the cast off, when bus_find_device is made const. 277 - */ 278 - dev_start = (struct device *)&from->dev; 279 - } 273 + if (from) 274 + dev_start = &from->dev; 280 275 dev = bus_find_device(&pci_bus_type, dev_start, (void *)id, 281 276 match_pci_dev_by_id); 282 277 if (dev)