diff options
Diffstat (limited to 'mm/vmstat.c')
-rw-r--r-- | mm/vmstat.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/mm/vmstat.c b/mm/vmstat.c index 9a66dc4aed43..9d824643a22f 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -640,6 +640,22 @@ const struct seq_operations vmstat_op = { | |||
640 | #endif /* CONFIG_PROC_FS */ | 640 | #endif /* CONFIG_PROC_FS */ |
641 | 641 | ||
642 | #ifdef CONFIG_SMP | 642 | #ifdef CONFIG_SMP |
643 | static DEFINE_PER_CPU(struct delayed_work, vmstat_work); | ||
644 | |||
645 | static void vmstat_update(struct work_struct *w) | ||
646 | { | ||
647 | refresh_cpu_vm_stats(smp_processor_id()); | ||
648 | schedule_delayed_work(&__get_cpu_var(vmstat_work), HZ); | ||
649 | } | ||
650 | |||
651 | static void __devinit start_cpu_timer(int cpu) | ||
652 | { | ||
653 | struct delayed_work *vmstat_work = &per_cpu(vmstat_work, cpu); | ||
654 | |||
655 | INIT_DELAYED_WORK(vmstat_work, vmstat_update); | ||
656 | schedule_delayed_work_on(cpu, vmstat_work, HZ + cpu); | ||
657 | } | ||
658 | |||
643 | /* | 659 | /* |
644 | * Use the cpu notifier to insure that the thresholds are recalculated | 660 | * Use the cpu notifier to insure that the thresholds are recalculated |
645 | * when necessary. | 661 | * when necessary. |
@@ -648,11 +664,22 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb, | |||
648 | unsigned long action, | 664 | unsigned long action, |
649 | void *hcpu) | 665 | void *hcpu) |
650 | { | 666 | { |
667 | long cpu = (long)hcpu; | ||
668 | |||
651 | switch (action) { | 669 | switch (action) { |
652 | case CPU_UP_PREPARE: | 670 | case CPU_ONLINE: |
653 | case CPU_UP_PREPARE_FROZEN: | 671 | case CPU_ONLINE_FROZEN: |
654 | case CPU_UP_CANCELED: | 672 | start_cpu_timer(cpu); |
655 | case CPU_UP_CANCELED_FROZEN: | 673 | break; |
674 | case CPU_DOWN_PREPARE: | ||
675 | case CPU_DOWN_PREPARE_FROZEN: | ||
676 | cancel_rearming_delayed_work(&per_cpu(vmstat_work, cpu)); | ||
677 | per_cpu(vmstat_work, cpu).work.func = NULL; | ||
678 | break; | ||
679 | case CPU_DOWN_FAILED: | ||
680 | case CPU_DOWN_FAILED_FROZEN: | ||
681 | start_cpu_timer(cpu); | ||
682 | break; | ||
656 | case CPU_DEAD: | 683 | case CPU_DEAD: |
657 | case CPU_DEAD_FROZEN: | 684 | case CPU_DEAD_FROZEN: |
658 | refresh_zone_stat_thresholds(); | 685 | refresh_zone_stat_thresholds(); |
@@ -668,8 +695,13 @@ static struct notifier_block __cpuinitdata vmstat_notifier = | |||
668 | 695 | ||
669 | int __init setup_vmstat(void) | 696 | int __init setup_vmstat(void) |
670 | { | 697 | { |
698 | int cpu; | ||
699 | |||
671 | refresh_zone_stat_thresholds(); | 700 | refresh_zone_stat_thresholds(); |
672 | register_cpu_notifier(&vmstat_notifier); | 701 | register_cpu_notifier(&vmstat_notifier); |
702 | |||
703 | for_each_online_cpu(cpu) | ||
704 | start_cpu_timer(cpu); | ||
673 | return 0; | 705 | return 0; |
674 | } | 706 | } |
675 | module_init(setup_vmstat) | 707 | module_init(setup_vmstat) |