Messages in this thread |  | | Date | Thu, 15 Nov 2001 00:28:22 -0800 | From | Andrew Morton <> | Subject | Re: [RFC] races in access to pci_devices |
| |
Jeff Garzik wrote: > > I haven't looked at it in over a year, but from a quick look, all the > list access look like they can be protected by a simple spinlock.
I don't think so? We do things like calling driver probe methods in the middle of a driver list walk.
An rwsem _may_ be suitable, but I'm not sure that we don't do a nested walk in some circumstances, and AFAIK our rwsems still are not safe for the same thread to do a down_read() twice.
Then there's the bus list, and the order of its lock wrt the device list.
One approach would be to use a spinlock and a per-device refcount. So something like:
spin_lock(&pci_dev_lock); dev = pci_dev_g(pci_devices.next); while (dev != pci_dev_g(&pci_devices)) { struct pci_dev *next;
pci_dev_get(dev); spin_unlock(&pci_dev_lock); diddle(dev); spin_lock(&pci_dev_lock); next = pci_dev_g(dev->global_list.next); pci_dev_put(dev); dev = next; } spin_unlock(&pci_dev_lock);
pci_dev_get(struct pci_dev *dev) { #ifdef CONFIG_SMP if (!spin_is_locked(&pci_dev_lock)) BUG(); #endif dev->refcount++; }
pci_dev_put(struct pci_dev *dev) { #ifdef CONFIG_SMP if (!spin_is_locked(&pci_dev_lock)) BUG(); #endif dev->refcount--; if (dev->refcount == 0) kfree(dev); }
I _think_ all this list traversal happens in process context now. Not sure about the PCI hotplug driver though.
It's really sticky. Which is why it isn't fixed :(
Sigh. Maybe go for an rwsem in 2.5, backport when it stops deadlocking?
- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |