diff options
-rw-r--r-- | MAINTAINERS | 33 | ||||
-rw-r--r-- | drivers/pci/host/pci-mvebu.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 38 | ||||
-rw-r--r-- | drivers/pci/remove.c | 4 | ||||
-rw-r--r-- | include/linux/kexec.h | 3 | ||||
-rw-r--r-- | include/linux/pci.h | 30 | ||||
-rw-r--r-- | kernel/kexec.c | 4 | ||||
-rw-r--r-- | kernel/workqueue.c | 32 |
8 files changed, 103 insertions, 46 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 00b655f117a7..94e3223b2bf4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -6465,19 +6465,52 @@ F: drivers/pci/ | |||
6465 | F: include/linux/pci* | 6465 | F: include/linux/pci* |
6466 | F: arch/x86/pci/ | 6466 | F: arch/x86/pci/ |
6467 | 6467 | ||
6468 | PCI DRIVER FOR IMX6 | ||
6469 | M: Richard Zhu <r65037@freescale.com> | ||
6470 | M: Shawn Guo <shawn.guo@linaro.org> | ||
6471 | L: linux-pci@vger.kernel.org | ||
6472 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
6473 | S: Maintained | ||
6474 | F: drivers/pci/host/*imx6* | ||
6475 | |||
6476 | PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support) | ||
6477 | M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> | ||
6478 | M: Jason Cooper <jason@lakedaemon.net> | ||
6479 | L: linux-pci@vger.kernel.org | ||
6480 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
6481 | S: Maintained | ||
6482 | F: drivers/pci/host/*mvebu* | ||
6483 | |||
6468 | PCI DRIVER FOR NVIDIA TEGRA | 6484 | PCI DRIVER FOR NVIDIA TEGRA |
6469 | M: Thierry Reding <thierry.reding@gmail.com> | 6485 | M: Thierry Reding <thierry.reding@gmail.com> |
6470 | L: linux-tegra@vger.kernel.org | 6486 | L: linux-tegra@vger.kernel.org |
6487 | L: linux-pci@vger.kernel.org | ||
6471 | S: Supported | 6488 | S: Supported |
6472 | F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt | 6489 | F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt |
6473 | F: drivers/pci/host/pci-tegra.c | 6490 | F: drivers/pci/host/pci-tegra.c |
6474 | 6491 | ||
6492 | PCI DRIVER FOR RENESAS R-CAR | ||
6493 | M: Simon Horman <horms@verge.net.au> | ||
6494 | L: linux-pci@vger.kernel.org | ||
6495 | L: linux-sh@vger.kernel.org | ||
6496 | S: Maintained | ||
6497 | F: drivers/pci/host/*rcar* | ||
6498 | |||
6475 | PCI DRIVER FOR SAMSUNG EXYNOS | 6499 | PCI DRIVER FOR SAMSUNG EXYNOS |
6476 | M: Jingoo Han <jg1.han@samsung.com> | 6500 | M: Jingoo Han <jg1.han@samsung.com> |
6477 | L: linux-pci@vger.kernel.org | 6501 | L: linux-pci@vger.kernel.org |
6502 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
6503 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) | ||
6478 | S: Maintained | 6504 | S: Maintained |
6479 | F: drivers/pci/host/pci-exynos.c | 6505 | F: drivers/pci/host/pci-exynos.c |
6480 | 6506 | ||
6507 | PCI DRIVER FOR SYNOPSIS DESIGNWARE | ||
6508 | M: Mohit Kumar <mohit.kumar@st.com> | ||
6509 | M: Jingoo Han <jg1.han@samsung.com> | ||
6510 | L: linux-pci@vger.kernel.org | ||
6511 | S: Maintained | ||
6512 | F: drivers/pci/host/*designware* | ||
6513 | |||
6481 | PCMCIA SUBSYSTEM | 6514 | PCMCIA SUBSYSTEM |
6482 | P: Linux PCMCIA Team | 6515 | P: Linux PCMCIA Team |
6483 | L: linux-pcmcia@lists.infradead.org | 6516 | L: linux-pcmcia@lists.infradead.org |
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index c269e430c760..2aa7b77c7c88 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c | |||
@@ -447,6 +447,11 @@ static int mvebu_sw_pci_bridge_read(struct mvebu_pcie_port *port, | |||
447 | *value = 0; | 447 | *value = 0; |
448 | break; | 448 | break; |
449 | 449 | ||
450 | case PCI_INTERRUPT_LINE: | ||
451 | /* LINE PIN MIN_GNT MAX_LAT */ | ||
452 | *value = 0; | ||
453 | break; | ||
454 | |||
450 | default: | 455 | default: |
451 | *value = 0xffffffff; | 456 | *value = 0xffffffff; |
452 | return PCIBIOS_BAD_REGISTER_NUMBER; | 457 | return PCIBIOS_BAD_REGISTER_NUMBER; |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 9042fdbd7244..25f0bc659164 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/cpu.h> | 19 | #include <linux/cpu.h> |
20 | #include <linux/pm_runtime.h> | 20 | #include <linux/pm_runtime.h> |
21 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
22 | #include <linux/kexec.h> | ||
22 | #include "pci.h" | 23 | #include "pci.h" |
23 | 24 | ||
24 | struct pci_dynid { | 25 | struct pci_dynid { |
@@ -288,12 +289,27 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
288 | int error, node; | 289 | int error, node; |
289 | struct drv_dev_and_id ddi = { drv, dev, id }; | 290 | struct drv_dev_and_id ddi = { drv, dev, id }; |
290 | 291 | ||
291 | /* Execute driver initialization on node where the device's | 292 | /* |
292 | bus is attached to. This way the driver likely allocates | 293 | * Execute driver initialization on node where the device is |
293 | its local memory on the right node without any need to | 294 | * attached. This way the driver likely allocates its local memory |
294 | change it. */ | 295 | * on the right node. |
296 | */ | ||
295 | node = dev_to_node(&dev->dev); | 297 | node = dev_to_node(&dev->dev); |
296 | if (node >= 0) { | 298 | |
299 | /* | ||
300 | * On NUMA systems, we are likely to call a PF probe function using | ||
301 | * work_on_cpu(). If that probe calls pci_enable_sriov() (which | ||
302 | * adds the VF devices via pci_bus_add_device()), we may re-enter | ||
303 | * this function to call the VF probe function. Calling | ||
304 | * work_on_cpu() again will cause a lockdep warning. Since VFs are | ||
305 | * always on the same node as the PF, we can work around this by | ||
306 | * avoiding work_on_cpu() when we're already on the correct node. | ||
307 | * | ||
308 | * Preemption is enabled, so it's theoretically unsafe to use | ||
309 | * numa_node_id(), but even if we run the probe function on the | ||
310 | * wrong node, it should be functionally correct. | ||
311 | */ | ||
312 | if (node >= 0 && node != numa_node_id()) { | ||
297 | int cpu; | 313 | int cpu; |
298 | 314 | ||
299 | get_online_cpus(); | 315 | get_online_cpus(); |
@@ -305,6 +321,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, | |||
305 | put_online_cpus(); | 321 | put_online_cpus(); |
306 | } else | 322 | } else |
307 | error = local_pci_probe(&ddi); | 323 | error = local_pci_probe(&ddi); |
324 | |||
308 | return error; | 325 | return error; |
309 | } | 326 | } |
310 | 327 | ||
@@ -399,12 +416,17 @@ static void pci_device_shutdown(struct device *dev) | |||
399 | pci_msi_shutdown(pci_dev); | 416 | pci_msi_shutdown(pci_dev); |
400 | pci_msix_shutdown(pci_dev); | 417 | pci_msix_shutdown(pci_dev); |
401 | 418 | ||
419 | #ifdef CONFIG_KEXEC | ||
402 | /* | 420 | /* |
403 | * Turn off Bus Master bit on the device to tell it to not | 421 | * If this is a kexec reboot, turn off Bus Master bit on the |
404 | * continue to do DMA. Don't touch devices in D3cold or unknown states. | 422 | * device to tell it to not continue to do DMA. Don't touch |
423 | * devices in D3cold or unknown states. | ||
424 | * If it is not a kexec reboot, firmware will hit the PCI | ||
425 | * devices with big hammer and stop their DMA any way. | ||
405 | */ | 426 | */ |
406 | if (pci_dev->current_state <= PCI_D3hot) | 427 | if (kexec_in_progress && (pci_dev->current_state <= PCI_D3hot)) |
407 | pci_clear_master(pci_dev); | 428 | pci_clear_master(pci_dev); |
429 | #endif | ||
408 | } | 430 | } |
409 | 431 | ||
410 | #ifdef CONFIG_PM | 432 | #ifdef CONFIG_PM |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 1576851028db..cc9337a71529 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -24,7 +24,7 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
24 | if (dev->is_added) { | 24 | if (dev->is_added) { |
25 | pci_proc_detach_device(dev); | 25 | pci_proc_detach_device(dev); |
26 | pci_remove_sysfs_dev_files(dev); | 26 | pci_remove_sysfs_dev_files(dev); |
27 | device_del(&dev->dev); | 27 | device_release_driver(&dev->dev); |
28 | dev->is_added = 0; | 28 | dev->is_added = 0; |
29 | } | 29 | } |
30 | 30 | ||
@@ -34,6 +34,8 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
34 | 34 | ||
35 | static void pci_destroy_dev(struct pci_dev *dev) | 35 | static void pci_destroy_dev(struct pci_dev *dev) |
36 | { | 36 | { |
37 | device_del(&dev->dev); | ||
38 | |||
37 | down_write(&pci_bus_sem); | 39 | down_write(&pci_bus_sem); |
38 | list_del(&dev->bus_list); | 40 | list_del(&dev->bus_list); |
39 | up_write(&pci_bus_sem); | 41 | up_write(&pci_bus_sem); |
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index d78d28a733b1..5fd33dc1fe3a 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
@@ -198,6 +198,9 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; | |||
198 | extern size_t vmcoreinfo_size; | 198 | extern size_t vmcoreinfo_size; |
199 | extern size_t vmcoreinfo_max_size; | 199 | extern size_t vmcoreinfo_max_size; |
200 | 200 | ||
201 | /* flag to track if kexec reboot is in progress */ | ||
202 | extern bool kexec_in_progress; | ||
203 | |||
201 | int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, | 204 | int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, |
202 | unsigned long long *crash_size, unsigned long long *crash_base); | 205 | unsigned long long *crash_size, unsigned long long *crash_base); |
203 | int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, | 206 | int parse_crashkernel_high(char *cmdline, unsigned long long system_ram, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 1084a15175e0..eb8078aeadc8 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1567,65 +1567,65 @@ enum pci_fixup_pass { | |||
1567 | /* Anonymous variables would be nice... */ | 1567 | /* Anonymous variables would be nice... */ |
1568 | #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ | 1568 | #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ |
1569 | class_shift, hook) \ | 1569 | class_shift, hook) \ |
1570 | static const struct pci_fixup __pci_fixup_##name __used \ | 1570 | static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used \ |
1571 | __attribute__((__section__(#section), aligned((sizeof(void *))))) \ | 1571 | __attribute__((__section__(#section), aligned((sizeof(void *))))) \ |
1572 | = { vendor, device, class, class_shift, hook }; | 1572 | = { vendor, device, class, class_shift, hook }; |
1573 | 1573 | ||
1574 | #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ | 1574 | #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ |
1575 | class_shift, hook) \ | 1575 | class_shift, hook) \ |
1576 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ | 1576 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ |
1577 | vendor##device##hook, vendor, device, class, class_shift, hook) | 1577 | hook, vendor, device, class, class_shift, hook) |
1578 | #define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class, \ | 1578 | #define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class, \ |
1579 | class_shift, hook) \ | 1579 | class_shift, hook) \ |
1580 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ | 1580 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ |
1581 | vendor##device##hook, vendor, device, class, class_shift, hook) | 1581 | hook, vendor, device, class, class_shift, hook) |
1582 | #define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \ | 1582 | #define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \ |
1583 | class_shift, hook) \ | 1583 | class_shift, hook) \ |
1584 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ | 1584 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ |
1585 | vendor##device##hook, vendor, device, class, class_shift, hook) | 1585 | hook, vendor, device, class, class_shift, hook) |
1586 | #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class, \ | 1586 | #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class, \ |
1587 | class_shift, hook) \ | 1587 | class_shift, hook) \ |
1588 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ | 1588 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ |
1589 | vendor##device##hook, vendor, device, class, class_shift, hook) | 1589 | hook, vendor, device, class, class_shift, hook) |
1590 | #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \ | 1590 | #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \ |
1591 | class_shift, hook) \ | 1591 | class_shift, hook) \ |
1592 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ | 1592 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ |
1593 | resume##vendor##device##hook, vendor, device, class, \ | 1593 | resume##hook, vendor, device, class, \ |
1594 | class_shift, hook) | 1594 | class_shift, hook) |
1595 | #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \ | 1595 | #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \ |
1596 | class_shift, hook) \ | 1596 | class_shift, hook) \ |
1597 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ | 1597 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ |
1598 | resume_early##vendor##device##hook, vendor, device, \ | 1598 | resume_early##hook, vendor, device, \ |
1599 | class, class_shift, hook) | 1599 | class, class_shift, hook) |
1600 | #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \ | 1600 | #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \ |
1601 | class_shift, hook) \ | 1601 | class_shift, hook) \ |
1602 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ | 1602 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ |
1603 | suspend##vendor##device##hook, vendor, device, class, \ | 1603 | suspend##hook, vendor, device, class, \ |
1604 | class_shift, hook) | 1604 | class_shift, hook) |
1605 | 1605 | ||
1606 | #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ | 1606 | #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ |
1607 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ | 1607 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ |
1608 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) | 1608 | hook, vendor, device, PCI_ANY_ID, 0, hook) |
1609 | #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ | 1609 | #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ |
1610 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ | 1610 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ |
1611 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) | 1611 | hook, vendor, device, PCI_ANY_ID, 0, hook) |
1612 | #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ | 1612 | #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ |
1613 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ | 1613 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ |
1614 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) | 1614 | hook, vendor, device, PCI_ANY_ID, 0, hook) |
1615 | #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ | 1615 | #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ |
1616 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ | 1616 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ |
1617 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) | 1617 | hook, vendor, device, PCI_ANY_ID, 0, hook) |
1618 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ | 1618 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ |
1619 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ | 1619 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ |
1620 | resume##vendor##device##hook, vendor, device, \ | 1620 | resume##hook, vendor, device, \ |
1621 | PCI_ANY_ID, 0, hook) | 1621 | PCI_ANY_ID, 0, hook) |
1622 | #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ | 1622 | #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ |
1623 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ | 1623 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ |
1624 | resume_early##vendor##device##hook, vendor, device, \ | 1624 | resume_early##hook, vendor, device, \ |
1625 | PCI_ANY_ID, 0, hook) | 1625 | PCI_ANY_ID, 0, hook) |
1626 | #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ | 1626 | #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ |
1627 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ | 1627 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ |
1628 | suspend##vendor##device##hook, vendor, device, \ | 1628 | suspend##hook, vendor, device, \ |
1629 | PCI_ANY_ID, 0, hook) | 1629 | PCI_ANY_ID, 0, hook) |
1630 | 1630 | ||
1631 | #ifdef CONFIG_PCI_QUIRKS | 1631 | #ifdef CONFIG_PCI_QUIRKS |
diff --git a/kernel/kexec.c b/kernel/kexec.c index 490afc03627e..d0d8fca54065 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -47,6 +47,9 @@ u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; | |||
47 | size_t vmcoreinfo_size; | 47 | size_t vmcoreinfo_size; |
48 | size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); | 48 | size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); |
49 | 49 | ||
50 | /* Flag to indicate we are going to kexec a new kernel */ | ||
51 | bool kexec_in_progress = false; | ||
52 | |||
50 | /* Location of the reserved area for the crash kernel */ | 53 | /* Location of the reserved area for the crash kernel */ |
51 | struct resource crashk_res = { | 54 | struct resource crashk_res = { |
52 | .name = "Crash kernel", | 55 | .name = "Crash kernel", |
@@ -1675,6 +1678,7 @@ int kernel_kexec(void) | |||
1675 | } else | 1678 | } else |
1676 | #endif | 1679 | #endif |
1677 | { | 1680 | { |
1681 | kexec_in_progress = true; | ||
1678 | kernel_restart_prepare(NULL); | 1682 | kernel_restart_prepare(NULL); |
1679 | printk(KERN_EMERG "Starting new kernel\n"); | 1683 | printk(KERN_EMERG "Starting new kernel\n"); |
1680 | machine_shutdown(); | 1684 | machine_shutdown(); |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index c66912be990f..b010eac595d2 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -2851,19 +2851,6 @@ already_gone: | |||
2851 | return false; | 2851 | return false; |
2852 | } | 2852 | } |
2853 | 2853 | ||
2854 | static bool __flush_work(struct work_struct *work) | ||
2855 | { | ||
2856 | struct wq_barrier barr; | ||
2857 | |||
2858 | if (start_flush_work(work, &barr)) { | ||
2859 | wait_for_completion(&barr.done); | ||
2860 | destroy_work_on_stack(&barr.work); | ||
2861 | return true; | ||
2862 | } else { | ||
2863 | return false; | ||
2864 | } | ||
2865 | } | ||
2866 | |||
2867 | /** | 2854 | /** |
2868 | * flush_work - wait for a work to finish executing the last queueing instance | 2855 | * flush_work - wait for a work to finish executing the last queueing instance |
2869 | * @work: the work to flush | 2856 | * @work: the work to flush |
@@ -2877,10 +2864,18 @@ static bool __flush_work(struct work_struct *work) | |||
2877 | */ | 2864 | */ |
2878 | bool flush_work(struct work_struct *work) | 2865 | bool flush_work(struct work_struct *work) |
2879 | { | 2866 | { |
2867 | struct wq_barrier barr; | ||
2868 | |||
2880 | lock_map_acquire(&work->lockdep_map); | 2869 | lock_map_acquire(&work->lockdep_map); |
2881 | lock_map_release(&work->lockdep_map); | 2870 | lock_map_release(&work->lockdep_map); |
2882 | 2871 | ||
2883 | return __flush_work(work); | 2872 | if (start_flush_work(work, &barr)) { |
2873 | wait_for_completion(&barr.done); | ||
2874 | destroy_work_on_stack(&barr.work); | ||
2875 | return true; | ||
2876 | } else { | ||
2877 | return false; | ||
2878 | } | ||
2884 | } | 2879 | } |
2885 | EXPORT_SYMBOL_GPL(flush_work); | 2880 | EXPORT_SYMBOL_GPL(flush_work); |
2886 | 2881 | ||
@@ -4832,14 +4827,7 @@ long work_on_cpu(int cpu, long (*fn)(void *), void *arg) | |||
4832 | 4827 | ||
4833 | INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); | 4828 | INIT_WORK_ONSTACK(&wfc.work, work_for_cpu_fn); |
4834 | schedule_work_on(cpu, &wfc.work); | 4829 | schedule_work_on(cpu, &wfc.work); |
4835 | 4830 | flush_work(&wfc.work); | |
4836 | /* | ||
4837 | * The work item is on-stack and can't lead to deadlock through | ||
4838 | * flushing. Use __flush_work() to avoid spurious lockdep warnings | ||
4839 | * when work_on_cpu()s are nested. | ||
4840 | */ | ||
4841 | __flush_work(&wfc.work); | ||
4842 | |||
4843 | return wfc.ret; | 4831 | return wfc.ret; |
4844 | } | 4832 | } |
4845 | EXPORT_SYMBOL_GPL(work_on_cpu); | 4833 | EXPORT_SYMBOL_GPL(work_on_cpu); |