rk, work); + + pw->result = local_pci_probe(&pw->ddi); +} + static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, const struct pci_device_id *id) { int error, node, cpu; + struct pci_probe_work pw; struct drv_dev_and_id ddi = { drv, dev, id }; /* @@ -361,38 +375,25 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, node = dev_to_node(&dev->dev); dev->is_probed = 1; - cpu_hotplug_disable(); - /* * Prevent nesting work_on_cpu() for the case where a Virtual Function * device is probed from work_on_cpu() of the Physical device. */ if (node < 0 || node >= MAX_NUMNODES || !node_online(node) || - pci_physfn_is_probed(dev)) { - cpu = nr_cpu_ids; - } else { - cpumask_var_t wq_domain_mask; - - if (!zalloc_cpumask_var(&wq_domain_mask, GFP_KERNEL)) { - error = -ENOMEM; - goto out; - } - cpumask_and(wq_domain_mask, - housekeeping_cpumask(HK_TYPE_WQ), - housekeeping_cpumask(HK_TYPE_DOMAIN)); - - cpu = cpumask_any_and(cpumask_of_node(node), - wq_domain_mask); - free_cpumask_var(wq_domain_mask); + pci_physfn_is_probed(dev) || (current->flags & PF_WQ_WORKER)) { + error = local_pci_probe(&ddi); + goto out; } - if (cpu < nr_cpu_ids) - error = work_on_cpu(cpu, local_pci_probe, &ddi); - else - error = local_pci_probe(&ddi); + INIT_WORK_ONSTACK(&pw.work, pci_probe_work_func); + pw.ddi = ddi; + queue_work_node(node, system_dfl_wq, &pw.work); + flush_work(&pw.work); + error = pw.result; + destroy_work_on_stack(&pw.work); + out: dev->is_probed = 0; - cpu_hotplug_enable(); return error; } Best Regards, Jinhui[PATCH] PCI: Avoid work_on_cpu() in async probe workers"Jinhui Guo" undefined undefined undefined undefined undefined undefined undefined undefined undefined undefined‹