]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
powerpc/eeh: Do early EEH init only when required
authorOliver O'Halloran <oohall@gmail.com>
Fri, 6 Mar 2020 07:39:01 +0000 (18:39 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 25 Mar 2020 01:09:38 +0000 (12:09 +1100)
The pci hotplug helper (pci_hp_add_devices()) calls
eeh_add_device_tree_early() to scan the device-tree for new PCI devices and
do the early EEH probe before the device is scanned. This early probe is a
no-op in a lot of cases because:

a) The early init is only required to satisfy a PAPR requirement that EEH
   be configured before we start doing config accesses. On PowerNV it is
   a no-op.

b) It's a no-op for devices that have already had their eeh_dev
   initialised.

There are four callers of pci_hp_add_devices():

1. arch/powerpc/kernel/eeh_driver.c
Here the hotplug helper is called when re-scanning pci_devs that
were removed during an EEH recovery pass. The EEH stat for each
removed device (the eeh_dev) is retained across a recovery pass
so the early init is a no-op in this case.

2. drivers/pci/hotplug/pnv_php.c
This is also a no-op since the PowerNV hotplug driver is, suprisingly,
PowerNV specific.

3. drivers/pci/hotplug/rpaphp_core.c
4. drivers/pci/hotplug/rpaphp_pci.c
In these two cases new devices have been hotplugged and FW has
provided new DT nodes for each. These are the only two cases where
the EEH we might have new PCI device nodes in the DT so these are
the only two cases where the early EEH probe needs to be done.

We can move the calls to eeh_add_device_tree_early() to the locations where
it's needed and remove it from the generic path. This is preparation for
making the early EEH probe pseries specific.

Reviewed-by: Sam Bobroff <sbobroff@linux.ibm.com>
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200306073904.4737-3-oohall@gmail.com
arch/powerpc/kernel/pci-hotplug.c
drivers/pci/hotplug/rpaphp_core.c
drivers/pci/hotplug/rpaphp_pci.c

index d6a67f814983d05c1b6fa299f3db638c1b216df3..bf83f76563a33812ce407b822f3cd51290085c58 100644 (file)
@@ -112,8 +112,6 @@ void pci_hp_add_devices(struct pci_bus *bus)
        struct pci_controller *phb;
        struct device_node *dn = pci_bus_to_OF_node(bus);
 
-       eeh_add_device_tree_early(PCI_DN(dn));
-
        phb = pci_bus_to_host(bus);
 
        mode = PCI_PROBE_NORMAL;
index 5d871ef231fd997b099ac4e61ee5b8f701898cb7..392a936c17dee5092c3c936f906c51042c48eebd 100644 (file)
@@ -493,6 +493,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
                return retval;
 
        if (state == PRESENT) {
+               eeh_add_device_tree_early(PCI_DN(slot->dn));
+
                pci_lock_rescan_remove();
                pci_hp_add_devices(slot->bus);
                pci_unlock_rescan_remove();
index beca61badeea4cc9015c10961915c5aec9176539..61ebbd832afb7c7c513f197f4af583f38128a0a9 100644 (file)
@@ -95,8 +95,10 @@ int rpaphp_enable_slot(struct slot *slot)
                        return -EINVAL;
                }
 
-               if (list_empty(&bus->devices))
+               if (list_empty(&bus->devices)) {
+                       eeh_add_device_tree_early(PCI_DN(slot->dn));
                        pci_hp_add_devices(bus);
+               }
 
                if (!list_empty(&bus->devices)) {
                        slot->state = CONFIGURED;