aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-07 17:55:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-07 17:55:46 -0400
commit467a9e1633043810259a7f5368fbcc1e84746137 (patch)
treec8a5bfd2a65455d7f6a59b312e348e069375bd9b /net/iucv
parentb8780c363d808a726a34793caa900923d32b6b80 (diff)
parenta0e247a8059223593f9c5c3d5c1fd50eedf415c0 (diff)
Merge tag 'cpu-hotplug-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull CPU hotplug notifiers registration fixes from Rafael Wysocki: "The purpose of this single series of commits from Srivatsa S Bhat (with a small piece from Gautham R Shenoy) touching multiple subsystems that use CPU hotplug notifiers is to provide a way to register them that will not lead to deadlocks with CPU online/offline operations as described in the changelog of commit 93ae4f978ca7f ("CPU hotplug: Provide lockless versions of callback registration functions"). The first three commits in the series introduce the API and document it and the rest simply goes through the users of CPU hotplug notifiers and converts them to using the new method" * tag 'cpu-hotplug-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (52 commits) net/iucv/iucv.c: Fix CPU hotplug callback registration net/core/flow.c: Fix CPU hotplug callback registration mm, zswap: Fix CPU hotplug callback registration mm, vmstat: Fix CPU hotplug callback registration profile: Fix CPU hotplug callback registration trace, ring-buffer: Fix CPU hotplug callback registration xen, balloon: Fix CPU hotplug callback registration hwmon, via-cputemp: Fix CPU hotplug callback registration hwmon, coretemp: Fix CPU hotplug callback registration thermal, x86-pkg-temp: Fix CPU hotplug callback registration octeon, watchdog: Fix CPU hotplug callback registration oprofile, nmi-timer: Fix CPU hotplug callback registration intel-idle: Fix CPU hotplug callback registration clocksource, dummy-timer: Fix CPU hotplug callback registration drivers/base/topology.c: Fix CPU hotplug callback registration acpi-cpufreq: Fix CPU hotplug callback registration zsmalloc: Fix CPU hotplug callback registration scsi, fcoe: Fix CPU hotplug callback registration scsi, bnx2fc: Fix CPU hotplug callback registration scsi, bnx2i: Fix CPU hotplug callback registration ...
Diffstat (limited to 'net/iucv')
-rw-r--r--net/iucv/iucv.c121
1 files changed, 57 insertions, 64 deletions
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index cd5b8ec9be04..79a0ce95799f 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -621,6 +621,42 @@ static void iucv_disable(void)
621 put_online_cpus(); 621 put_online_cpus();
622} 622}
623 623
624static void free_iucv_data(int cpu)
625{
626 kfree(iucv_param_irq[cpu]);
627 iucv_param_irq[cpu] = NULL;
628 kfree(iucv_param[cpu]);
629 iucv_param[cpu] = NULL;
630 kfree(iucv_irq_data[cpu]);
631 iucv_irq_data[cpu] = NULL;
632}
633
634static int alloc_iucv_data(int cpu)
635{
636 /* Note: GFP_DMA used to get memory below 2G */
637 iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
638 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
639 if (!iucv_irq_data[cpu])
640 goto out_free;
641
642 /* Allocate parameter blocks. */
643 iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
644 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
645 if (!iucv_param[cpu])
646 goto out_free;
647
648 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
649 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
650 if (!iucv_param_irq[cpu])
651 goto out_free;
652
653 return 0;
654
655out_free:
656 free_iucv_data(cpu);
657 return -ENOMEM;
658}
659
624static int iucv_cpu_notify(struct notifier_block *self, 660static int iucv_cpu_notify(struct notifier_block *self,
625 unsigned long action, void *hcpu) 661 unsigned long action, void *hcpu)
626{ 662{
@@ -630,38 +666,14 @@ static int iucv_cpu_notify(struct notifier_block *self,
630 switch (action) { 666 switch (action) {
631 case CPU_UP_PREPARE: 667 case CPU_UP_PREPARE:
632 case CPU_UP_PREPARE_FROZEN: 668 case CPU_UP_PREPARE_FROZEN:
633 iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data), 669 if (alloc_iucv_data(cpu))
634 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
635 if (!iucv_irq_data[cpu])
636 return notifier_from_errno(-ENOMEM);
637
638 iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param),
639 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
640 if (!iucv_param[cpu]) {
641 kfree(iucv_irq_data[cpu]);
642 iucv_irq_data[cpu] = NULL;
643 return notifier_from_errno(-ENOMEM); 670 return notifier_from_errno(-ENOMEM);
644 }
645 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
646 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
647 if (!iucv_param_irq[cpu]) {
648 kfree(iucv_param[cpu]);
649 iucv_param[cpu] = NULL;
650 kfree(iucv_irq_data[cpu]);
651 iucv_irq_data[cpu] = NULL;
652 return notifier_from_errno(-ENOMEM);
653 }
654 break; 671 break;
655 case CPU_UP_CANCELED: 672 case CPU_UP_CANCELED:
656 case CPU_UP_CANCELED_FROZEN: 673 case CPU_UP_CANCELED_FROZEN:
657 case CPU_DEAD: 674 case CPU_DEAD:
658 case CPU_DEAD_FROZEN: 675 case CPU_DEAD_FROZEN:
659 kfree(iucv_param_irq[cpu]); 676 free_iucv_data(cpu);
660 iucv_param_irq[cpu] = NULL;
661 kfree(iucv_param[cpu]);
662 iucv_param[cpu] = NULL;
663 kfree(iucv_irq_data[cpu]);
664 iucv_irq_data[cpu] = NULL;
665 break; 677 break;
666 case CPU_ONLINE: 678 case CPU_ONLINE:
667 case CPU_ONLINE_FROZEN: 679 case CPU_ONLINE_FROZEN:
@@ -2025,33 +2037,20 @@ static int __init iucv_init(void)
2025 goto out_int; 2037 goto out_int;
2026 } 2038 }
2027 2039
2028 for_each_online_cpu(cpu) { 2040 cpu_notifier_register_begin();
2029 /* Note: GFP_DMA used to get memory below 2G */
2030 iucv_irq_data[cpu] = kmalloc_node(sizeof(struct iucv_irq_data),
2031 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
2032 if (!iucv_irq_data[cpu]) {
2033 rc = -ENOMEM;
2034 goto out_free;
2035 }
2036 2041
2037 /* Allocate parameter blocks. */ 2042 for_each_online_cpu(cpu) {
2038 iucv_param[cpu] = kmalloc_node(sizeof(union iucv_param), 2043 if (alloc_iucv_data(cpu)) {
2039 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
2040 if (!iucv_param[cpu]) {
2041 rc = -ENOMEM;
2042 goto out_free;
2043 }
2044 iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
2045 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
2046 if (!iucv_param_irq[cpu]) {
2047 rc = -ENOMEM; 2044 rc = -ENOMEM;
2048 goto out_free; 2045 goto out_free;
2049 } 2046 }
2050
2051 } 2047 }
2052 rc = register_hotcpu_notifier(&iucv_cpu_notifier); 2048 rc = __register_hotcpu_notifier(&iucv_cpu_notifier);
2053 if (rc) 2049 if (rc)
2054 goto out_free; 2050 goto out_free;
2051
2052 cpu_notifier_register_done();
2053
2055 rc = register_reboot_notifier(&iucv_reboot_notifier); 2054 rc = register_reboot_notifier(&iucv_reboot_notifier);
2056 if (rc) 2055 if (rc)
2057 goto out_cpu; 2056 goto out_cpu;
@@ -2069,16 +2068,14 @@ static int __init iucv_init(void)
2069out_reboot: 2068out_reboot:
2070 unregister_reboot_notifier(&iucv_reboot_notifier); 2069 unregister_reboot_notifier(&iucv_reboot_notifier);
2071out_cpu: 2070out_cpu:
2072 unregister_hotcpu_notifier(&iucv_cpu_notifier); 2071 cpu_notifier_register_begin();
2072 __unregister_hotcpu_notifier(&iucv_cpu_notifier);
2073out_free: 2073out_free:
2074 for_each_possible_cpu(cpu) { 2074 for_each_possible_cpu(cpu)
2075 kfree(iucv_param_irq[cpu]); 2075 free_iucv_data(cpu);
2076 iucv_param_irq[cpu] = NULL; 2076
2077 kfree(iucv_param[cpu]); 2077 cpu_notifier_register_done();
2078 iucv_param[cpu] = NULL; 2078
2079 kfree(iucv_irq_data[cpu]);
2080 iucv_irq_data[cpu] = NULL;
2081 }
2082 root_device_unregister(iucv_root); 2079 root_device_unregister(iucv_root);
2083out_int: 2080out_int:
2084 unregister_external_interrupt(0x4000, iucv_external_interrupt); 2081 unregister_external_interrupt(0x4000, iucv_external_interrupt);
@@ -2105,15 +2102,11 @@ static void __exit iucv_exit(void)
2105 kfree(p); 2102 kfree(p);
2106 spin_unlock_irq(&iucv_queue_lock); 2103 spin_unlock_irq(&iucv_queue_lock);
2107 unregister_reboot_notifier(&iucv_reboot_notifier); 2104 unregister_reboot_notifier(&iucv_reboot_notifier);
2108 unregister_hotcpu_notifier(&iucv_cpu_notifier); 2105 cpu_notifier_register_begin();
2109 for_each_possible_cpu(cpu) { 2106 __unregister_hotcpu_notifier(&iucv_cpu_notifier);
2110 kfree(iucv_param_irq[cpu]); 2107 for_each_possible_cpu(cpu)
2111 iucv_param_irq[cpu] = NULL; 2108 free_iucv_data(cpu);
2112 kfree(iucv_param[cpu]); 2109 cpu_notifier_register_done();
2113 iucv_param[cpu] = NULL;
2114 kfree(iucv_irq_data[cpu]);
2115 iucv_irq_data[cpu] = NULL;
2116 }
2117 root_device_unregister(iucv_root); 2110 root_device_unregister(iucv_root);
2118 bus_unregister(&iucv_bus); 2111 bus_unregister(&iucv_bus);
2119 unregister_external_interrupt(0x4000, iucv_external_interrupt); 2112 unregister_external_interrupt(0x4000, iucv_external_interrupt);