Skip to content

Commit ee061da

Browse files
keithbuschbjorn-helgaas
authored andcommitted
PCI: Convert __pci_walk_bus() to be recursive
The original implementation of __pci_walk_bus() chose a non-recursive walk, presumably as a precaution on stack use. We do recursive bus walking in other places though. For example: pci_bus_resettable() pci_stop_bus_device() pci_remove_bus_device() pci_bus_allocate_dev_resources() So recursive pci bus walking is well tested and safe, and is easier to follow. Convert __pci_walk_bus() to be recursive to make it easier to introduce finer grain locking in the future. Link: https://lore.kernel.org/r/20241022224851.340648-5-kbusch@meta.com Signed-off-by: Keith Busch <kbusch@kernel.org> [bhelgaas: commit log] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1 parent 4d6dcd6 commit ee061da

File tree

1 file changed

+11
-25
lines changed

1 file changed

+11
-25
lines changed

drivers/pci/bus.c

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -389,37 +389,23 @@ void pci_bus_add_devices(const struct pci_bus *bus)
389389
}
390390
EXPORT_SYMBOL(pci_bus_add_devices);
391391

392-
static void __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
393-
void *userdata)
392+
static int __pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
393+
void *userdata)
394394
{
395395
struct pci_dev *dev;
396-
struct pci_bus *bus;
397-
struct list_head *next;
398-
int retval;
396+
int ret = 0;
399397

400-
bus = top;
401-
next = top->devices.next;
402-
for (;;) {
403-
if (next == &bus->devices) {
404-
/* end of this bus, go up or finish */
405-
if (bus == top)
398+
list_for_each_entry(dev, &top->devices, bus_list) {
399+
ret = cb(dev, userdata);
400+
if (ret)
401+
break;
402+
if (dev->subordinate) {
403+
ret = __pci_walk_bus(dev->subordinate, cb, userdata);
404+
if (ret)
406405
break;
407-
next = bus->self->bus_list.next;
408-
bus = bus->self->bus;
409-
continue;
410406
}
411-
dev = list_entry(next, struct pci_dev, bus_list);
412-
if (dev->subordinate) {
413-
/* this is a pci-pci bridge, do its devices next */
414-
next = dev->subordinate->devices.next;
415-
bus = dev->subordinate;
416-
} else
417-
next = dev->bus_list.next;
418-
419-
retval = cb(dev, userdata);
420-
if (retval)
421-
break;
422407
}
408+
return ret;
423409
}
424410

425411
/**

0 commit comments

Comments
 (0)