]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mm/vmstat: Convert to hotplug state machine
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>
Tue, 29 Nov 2016 14:52:21 +0000 (15:52 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 1 Dec 2016 23:52:35 +0000 (00:52 +0100)
Install the callbacks via the state machine, but do not invoke them as we
can initialize the node state without calling the callbacks on all online
CPUs.

start_shepherd_timer() is now called outside the get_online_cpus() block
which is safe as it only operates on cpu possible mask.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org
Cc: rt@linutronix.de
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Vlastimil Babka <vbabka@suse.cz>
Link: http://lkml.kernel.org/r/20161129145221.ffc3kg3hd7lxiwj6@linutronix.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
include/linux/cpuhotplug.h
mm/vmstat.c

index 18bcfeb2463e1bdf1b693d362e425a38e65fefd8..4ebd1bc27f8d6260b9a035859c8be76d0ddfae3e 100644 (file)
@@ -20,6 +20,7 @@ enum cpuhp_state {
        CPUHP_VIRT_NET_DEAD,
        CPUHP_SLUB_DEAD,
        CPUHP_MM_WRITEBACK_DEAD,
+       CPUHP_MM_VMSTAT_DEAD,
        CPUHP_SOFTIRQ_DEAD,
        CPUHP_NET_MVNETA_DEAD,
        CPUHP_CPUIDLE_DEAD,
index 5152cd1c490f8cff9d3fe129c3adb82b409cc44f..7c28df36f50ff009963ff1f04cf0be848dd0fa13 100644 (file)
@@ -1728,64 +1728,58 @@ static void __init init_cpu_node_state(void)
        }
 }
 
-static void vmstat_cpu_dead(int node)
+static int vmstat_cpu_online(unsigned int cpu)
+{
+       refresh_zone_stat_thresholds();
+       node_set_state(cpu_to_node(cpu), N_CPU);
+       return 0;
+}
+
+static int vmstat_cpu_down_prep(unsigned int cpu)
+{
+       cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu));
+       return 0;
+}
+
+static int vmstat_cpu_dead(unsigned int cpu)
 {
        const struct cpumask *node_cpus;
+       int node;
 
+       node = cpu_to_node(cpu);
+
+       refresh_zone_stat_thresholds();
        node_cpus = cpumask_of_node(node);
        if (cpumask_weight(node_cpus) > 0)
-               return;
+               return 0;
 
        node_clear_state(node, N_CPU);
+       return 0;
 }
 
-/*
- * Use the cpu notifier to insure that the thresholds are recalculated
- * when necessary.
- */
-static int vmstat_cpuup_callback(struct notifier_block *nfb,
-               unsigned long action,
-               void *hcpu)
-{
-       long cpu = (long)hcpu;
-
-       switch (action) {
-       case CPU_ONLINE:
-       case CPU_ONLINE_FROZEN:
-               refresh_zone_stat_thresholds();
-               node_set_state(cpu_to_node(cpu), N_CPU);
-               break;
-       case CPU_DOWN_PREPARE:
-       case CPU_DOWN_PREPARE_FROZEN:
-               cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu));
-               break;
-       case CPU_DOWN_FAILED:
-       case CPU_DOWN_FAILED_FROZEN:
-               break;
-       case CPU_DEAD:
-       case CPU_DEAD_FROZEN:
-               refresh_zone_stat_thresholds();
-               vmstat_cpu_dead(cpu_to_node(cpu));
-               break;
-       default:
-               break;
-       }
-       return NOTIFY_OK;
-}
-
-static struct notifier_block vmstat_notifier =
-       { &vmstat_cpuup_callback, NULL, 0 };
 #endif
 
 static int __init setup_vmstat(void)
 {
 #ifdef CONFIG_SMP
-       cpu_notifier_register_begin();
-       __register_cpu_notifier(&vmstat_notifier);
+       int ret;
+
+       ret = cpuhp_setup_state_nocalls(CPUHP_MM_VMSTAT_DEAD, "mm/vmstat:dead",
+                                       NULL, vmstat_cpu_dead);
+       if (ret < 0)
+               pr_err("vmstat: failed to register 'dead' hotplug state\n");
+
+       ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "mm/vmstat:online",
+                                       vmstat_cpu_online,
+                                       vmstat_cpu_down_prep);
+       if (ret < 0)
+               pr_err("vmstat: failed to register 'online' hotplug state\n");
+
+       get_online_cpus();
        init_cpu_node_state();
+       put_online_cpus();
 
        start_shepherd_timer();
-       cpu_notifier_register_done();
 #endif
 #ifdef CONFIG_PROC_FS
        proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);