PCI: Avoid unnecessary CPU switch when calling driver .probe() method

If we are already on a CPU local to the device, call the driver .probe()
method directly without using work_on_cpu().

This is a workaround for a lockdep warning in the following scenario:

  pci_call_probe
    work_on_cpu(cpu, local_pci_probe, ...)
      driver .probe
        pci_enable_sriov
          ...
            pci_bus_add_device
              ...
                pci_call_probe
                  work_on_cpu(cpu, local_pci_probe, ...)

It would be better to fix PCI so we don't call VF driver .probe() methods
from inside a PF driver .probe() method, but that's a bigger project.

[bhelgaas: open bugzilla, rework comments & changelog]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=65071
Link: http://lkml.kernel.org/r/CAE9FiQXYQEAZ=0sG6+2OdffBqfLS9MpoN1xviRR9aDbxPxcKxQ@mail.gmail.com
Link: http://lkml.kernel.org/r/20130624195942.40795.27292.stgit@ahduyck-cp1.jf.intel.com
Tested-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Yinghai Lu <yinghai@kernel.org>
This commit is contained in:
Alexander Duyck 2013-11-18 10:59:59 -07:00 committed by Bjorn Helgaas
parent 6ce4eac1f6
commit 12c3156f10

View file

@ -288,12 +288,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
int error, node;
struct drv_dev_and_id ddi = { drv, dev, id };
/* Execute driver initialization on node where the device's
bus is attached to. This way the driver likely allocates
its local memory on the right node without any need to
change it. */
/*
* Execute driver initialization on node where the device is
* attached. This way the driver likely allocates its local memory
* on the right node.
*/
node = dev_to_node(&dev->dev);
if (node >= 0) {
/*
* On NUMA systems, we are likely to call a PF probe function using
* work_on_cpu(). If that probe calls pci_enable_sriov() (which
* adds the VF devices via pci_bus_add_device()), we may re-enter
* this function to call the VF probe function. Calling
* work_on_cpu() again will cause a lockdep warning. Since VFs are
* always on the same node as the PF, we can work around this by
* avoiding work_on_cpu() when we're already on the correct node.
*
* Preemption is enabled, so it's theoretically unsafe to use
* numa_node_id(), but even if we run the probe function on the
* wrong node, it should be functionally correct.
*/
if (node >= 0 && node != numa_node_id()) {
int cpu;
get_online_cpus();
@ -305,6 +320,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
put_online_cpus();
} else
error = local_pci_probe(&ddi);
return error;
}