]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
PCI: WARN (not BUG()) when we fail to assign optional resources
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Sun, 11 May 2025 21:52:23 +0000 (00:52 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 2 Jun 2025 14:31:53 +0000 (09:31 -0500)
Resource fitting/assignment code checks if there's a remainder in
add_list (aka. realloc_head in the inner functions) using BUG_ON().
This problem typically results in a mere PCI device resource assignment
failure which does not warrant using BUG_ON(). The machine could well
come up usable even if this condition occurs because the realloc_head
relates to resources which are optional anyway.

Change BUG_ON() to WARN_ON_ONCE() and free the list if it's not empty.

[bhelgaas: subject]
Reported-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://lore.kernel.org/linux-pci/5f103643-5e1c-43c6-b8fe-9617d3b5447c@linaro.org
Link: https://lore.kernel.org/r/20250511215223.7131-1-ilpo.jarvinen@linux.intel.com
drivers/pci/setup-bus.c

index 54d6f4fa3ce166ea4f62e4018c25f43ad3a4c8c3..a0d815557f5cf9927c3aecd0925c04d4e661a952 100644 (file)
@@ -2298,8 +2298,8 @@ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)
 
                /* Depth last, allocate resources and update the hardware. */
                __pci_bus_assign_resources(bus, add_list, &fail_head);
-               if (add_list)
-                       BUG_ON(!list_empty(add_list));
+               if (WARN_ON_ONCE(add_list && !list_empty(add_list)))
+                       free_list(add_list);
                tried_times++;
 
                /* Any device complain? */
@@ -2361,7 +2361,8 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
                pci_bridge_distribute_available_resources(bridge, &add_list);
 
                __pci_bridge_assign_resources(bridge, &add_list, &fail_head);
-               BUG_ON(!list_empty(&add_list));
+               if (WARN_ON_ONCE(!list_empty(&add_list)))
+                       free_list(&add_list);
                tried_times++;
 
                if (list_empty(&fail_head))
@@ -2437,7 +2438,8 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
 
        __pci_bus_size_bridges(bridge->subordinate, &added);
        __pci_bridge_assign_resources(bridge, &added, &failed);
-       BUG_ON(!list_empty(&added));
+       if (WARN_ON_ONCE(!list_empty(&added)))
+               free_list(&added);
 
        if (!list_empty(&failed)) {
                ret = -ENOSPC;
@@ -2493,6 +2495,7 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
                        __pci_bus_size_bridges(dev->subordinate, &add_list);
        up_read(&pci_bus_sem);
        __pci_bus_assign_resources(bus, &add_list, NULL);
-       BUG_ON(!list_empty(&add_list));
+       if (WARN_ON_ONCE(!list_empty(&add_list)))
+               free_list(&add_list);
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bus_resources);