diff options
author | Glauber Costa <glommer@parallels.com> | 2011-11-28 11:45:17 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-12-06 03:06:38 -0500 |
commit | 3292beb340c76884427faa1f5d6085719477d889 (patch) | |
tree | cb7e431b2a15fa66ef5278d485131bac7a125fbd /kernel | |
parent | 786d6dc7aeb2bfbfe417507b7beb83919f319db3 (diff) |
sched/accounting: Change cpustat fields to an array
This patch changes fields in cpustat from a structure, to an
u64 array. Math gets easier, and the code is more flexible.
Signed-off-by: Glauber Costa <glommer@parallels.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Paul Tuner <pjt@google.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1322498719-2255-2-git-send-email-glommer@parallels.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched/core.c | 78 |
1 files changed, 40 insertions, 38 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 699ff1499a8a..dbbe35ff93fc 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -896,14 +896,14 @@ static void update_rq_clock_task(struct rq *rq, s64 delta) | |||
896 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING | 896 | #ifdef CONFIG_IRQ_TIME_ACCOUNTING |
897 | static int irqtime_account_hi_update(void) | 897 | static int irqtime_account_hi_update(void) |
898 | { | 898 | { |
899 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 899 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
900 | unsigned long flags; | 900 | unsigned long flags; |
901 | u64 latest_ns; | 901 | u64 latest_ns; |
902 | int ret = 0; | 902 | int ret = 0; |
903 | 903 | ||
904 | local_irq_save(flags); | 904 | local_irq_save(flags); |
905 | latest_ns = this_cpu_read(cpu_hardirq_time); | 905 | latest_ns = this_cpu_read(cpu_hardirq_time); |
906 | if (cputime64_gt(nsecs_to_cputime64(latest_ns), cpustat->irq)) | 906 | if (cputime64_gt(nsecs_to_cputime64(latest_ns), cpustat[CPUTIME_IRQ])) |
907 | ret = 1; | 907 | ret = 1; |
908 | local_irq_restore(flags); | 908 | local_irq_restore(flags); |
909 | return ret; | 909 | return ret; |
@@ -911,14 +911,14 @@ static int irqtime_account_hi_update(void) | |||
911 | 911 | ||
912 | static int irqtime_account_si_update(void) | 912 | static int irqtime_account_si_update(void) |
913 | { | 913 | { |
914 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 914 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
915 | unsigned long flags; | 915 | unsigned long flags; |
916 | u64 latest_ns; | 916 | u64 latest_ns; |
917 | int ret = 0; | 917 | int ret = 0; |
918 | 918 | ||
919 | local_irq_save(flags); | 919 | local_irq_save(flags); |
920 | latest_ns = this_cpu_read(cpu_softirq_time); | 920 | latest_ns = this_cpu_read(cpu_softirq_time); |
921 | if (cputime64_gt(nsecs_to_cputime64(latest_ns), cpustat->softirq)) | 921 | if (cputime64_gt(nsecs_to_cputime64(latest_ns), cpustat[CPUTIME_SOFTIRQ])) |
922 | ret = 1; | 922 | ret = 1; |
923 | local_irq_restore(flags); | 923 | local_irq_restore(flags); |
924 | return ret; | 924 | return ret; |
@@ -2500,8 +2500,10 @@ unlock: | |||
2500 | #endif | 2500 | #endif |
2501 | 2501 | ||
2502 | DEFINE_PER_CPU(struct kernel_stat, kstat); | 2502 | DEFINE_PER_CPU(struct kernel_stat, kstat); |
2503 | DEFINE_PER_CPU(struct kernel_cpustat, kernel_cpustat); | ||
2503 | 2504 | ||
2504 | EXPORT_PER_CPU_SYMBOL(kstat); | 2505 | EXPORT_PER_CPU_SYMBOL(kstat); |
2506 | EXPORT_PER_CPU_SYMBOL(kernel_cpustat); | ||
2505 | 2507 | ||
2506 | /* | 2508 | /* |
2507 | * Return any ns on the sched_clock that have not yet been accounted in | 2509 | * Return any ns on the sched_clock that have not yet been accounted in |
@@ -2563,8 +2565,9 @@ unsigned long long task_sched_runtime(struct task_struct *p) | |||
2563 | void account_user_time(struct task_struct *p, cputime_t cputime, | 2565 | void account_user_time(struct task_struct *p, cputime_t cputime, |
2564 | cputime_t cputime_scaled) | 2566 | cputime_t cputime_scaled) |
2565 | { | 2567 | { |
2566 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2568 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
2567 | cputime64_t tmp; | 2569 | u64 tmp; |
2570 | int index; | ||
2568 | 2571 | ||
2569 | /* Add user time to process. */ | 2572 | /* Add user time to process. */ |
2570 | p->utime = cputime_add(p->utime, cputime); | 2573 | p->utime = cputime_add(p->utime, cputime); |
@@ -2573,10 +2576,9 @@ void account_user_time(struct task_struct *p, cputime_t cputime, | |||
2573 | 2576 | ||
2574 | /* Add user time to cpustat. */ | 2577 | /* Add user time to cpustat. */ |
2575 | tmp = cputime_to_cputime64(cputime); | 2578 | tmp = cputime_to_cputime64(cputime); |
2576 | if (TASK_NICE(p) > 0) | 2579 | |
2577 | cpustat->nice = cputime64_add(cpustat->nice, tmp); | 2580 | index = (TASK_NICE(p) > 0) ? CPUTIME_NICE : CPUTIME_USER; |
2578 | else | 2581 | cpustat[index] += tmp; |
2579 | cpustat->user = cputime64_add(cpustat->user, tmp); | ||
2580 | 2582 | ||
2581 | cpuacct_update_stats(p, CPUACCT_STAT_USER, cputime); | 2583 | cpuacct_update_stats(p, CPUACCT_STAT_USER, cputime); |
2582 | /* Account for user time used */ | 2584 | /* Account for user time used */ |
@@ -2592,8 +2594,8 @@ void account_user_time(struct task_struct *p, cputime_t cputime, | |||
2592 | static void account_guest_time(struct task_struct *p, cputime_t cputime, | 2594 | static void account_guest_time(struct task_struct *p, cputime_t cputime, |
2593 | cputime_t cputime_scaled) | 2595 | cputime_t cputime_scaled) |
2594 | { | 2596 | { |
2595 | cputime64_t tmp; | 2597 | u64 tmp; |
2596 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2598 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
2597 | 2599 | ||
2598 | tmp = cputime_to_cputime64(cputime); | 2600 | tmp = cputime_to_cputime64(cputime); |
2599 | 2601 | ||
@@ -2605,11 +2607,11 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime, | |||
2605 | 2607 | ||
2606 | /* Add guest time to cpustat. */ | 2608 | /* Add guest time to cpustat. */ |
2607 | if (TASK_NICE(p) > 0) { | 2609 | if (TASK_NICE(p) > 0) { |
2608 | cpustat->nice = cputime64_add(cpustat->nice, tmp); | 2610 | cpustat[CPUTIME_NICE] += tmp; |
2609 | cpustat->guest_nice = cputime64_add(cpustat->guest_nice, tmp); | 2611 | cpustat[CPUTIME_GUEST_NICE] += tmp; |
2610 | } else { | 2612 | } else { |
2611 | cpustat->user = cputime64_add(cpustat->user, tmp); | 2613 | cpustat[CPUTIME_USER] += tmp; |
2612 | cpustat->guest = cputime64_add(cpustat->guest, tmp); | 2614 | cpustat[CPUTIME_GUEST] += tmp; |
2613 | } | 2615 | } |
2614 | } | 2616 | } |
2615 | 2617 | ||
@@ -2622,9 +2624,10 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime, | |||
2622 | */ | 2624 | */ |
2623 | static inline | 2625 | static inline |
2624 | void __account_system_time(struct task_struct *p, cputime_t cputime, | 2626 | void __account_system_time(struct task_struct *p, cputime_t cputime, |
2625 | cputime_t cputime_scaled, cputime64_t *target_cputime64) | 2627 | cputime_t cputime_scaled, int index) |
2626 | { | 2628 | { |
2627 | cputime64_t tmp = cputime_to_cputime64(cputime); | 2629 | u64 tmp = cputime_to_cputime64(cputime); |
2630 | u64 *cpustat = kcpustat_this_cpu->cpustat; | ||
2628 | 2631 | ||
2629 | /* Add system time to process. */ | 2632 | /* Add system time to process. */ |
2630 | p->stime = cputime_add(p->stime, cputime); | 2633 | p->stime = cputime_add(p->stime, cputime); |
@@ -2632,7 +2635,7 @@ void __account_system_time(struct task_struct *p, cputime_t cputime, | |||
2632 | account_group_system_time(p, cputime); | 2635 | account_group_system_time(p, cputime); |
2633 | 2636 | ||
2634 | /* Add system time to cpustat. */ | 2637 | /* Add system time to cpustat. */ |
2635 | *target_cputime64 = cputime64_add(*target_cputime64, tmp); | 2638 | cpustat[index] += tmp; |
2636 | cpuacct_update_stats(p, CPUACCT_STAT_SYSTEM, cputime); | 2639 | cpuacct_update_stats(p, CPUACCT_STAT_SYSTEM, cputime); |
2637 | 2640 | ||
2638 | /* Account for system time used */ | 2641 | /* Account for system time used */ |
@@ -2649,8 +2652,7 @@ void __account_system_time(struct task_struct *p, cputime_t cputime, | |||
2649 | void account_system_time(struct task_struct *p, int hardirq_offset, | 2652 | void account_system_time(struct task_struct *p, int hardirq_offset, |
2650 | cputime_t cputime, cputime_t cputime_scaled) | 2653 | cputime_t cputime, cputime_t cputime_scaled) |
2651 | { | 2654 | { |
2652 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2655 | int index; |
2653 | cputime64_t *target_cputime64; | ||
2654 | 2656 | ||
2655 | if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { | 2657 | if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) { |
2656 | account_guest_time(p, cputime, cputime_scaled); | 2658 | account_guest_time(p, cputime, cputime_scaled); |
@@ -2658,13 +2660,13 @@ void account_system_time(struct task_struct *p, int hardirq_offset, | |||
2658 | } | 2660 | } |
2659 | 2661 | ||
2660 | if (hardirq_count() - hardirq_offset) | 2662 | if (hardirq_count() - hardirq_offset) |
2661 | target_cputime64 = &cpustat->irq; | 2663 | index = CPUTIME_IRQ; |
2662 | else if (in_serving_softirq()) | 2664 | else if (in_serving_softirq()) |
2663 | target_cputime64 = &cpustat->softirq; | 2665 | index = CPUTIME_SOFTIRQ; |
2664 | else | 2666 | else |
2665 | target_cputime64 = &cpustat->system; | 2667 | index = CPUTIME_SYSTEM; |
2666 | 2668 | ||
2667 | __account_system_time(p, cputime, cputime_scaled, target_cputime64); | 2669 | __account_system_time(p, cputime, cputime_scaled, index); |
2668 | } | 2670 | } |
2669 | 2671 | ||
2670 | /* | 2672 | /* |
@@ -2673,10 +2675,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset, | |||
2673 | */ | 2675 | */ |
2674 | void account_steal_time(cputime_t cputime) | 2676 | void account_steal_time(cputime_t cputime) |
2675 | { | 2677 | { |
2676 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2678 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
2677 | cputime64_t cputime64 = cputime_to_cputime64(cputime); | 2679 | u64 cputime64 = cputime_to_cputime64(cputime); |
2678 | 2680 | ||
2679 | cpustat->steal = cputime64_add(cpustat->steal, cputime64); | 2681 | cpustat[CPUTIME_STEAL] += cputime64; |
2680 | } | 2682 | } |
2681 | 2683 | ||
2682 | /* | 2684 | /* |
@@ -2685,14 +2687,14 @@ void account_steal_time(cputime_t cputime) | |||
2685 | */ | 2687 | */ |
2686 | void account_idle_time(cputime_t cputime) | 2688 | void account_idle_time(cputime_t cputime) |
2687 | { | 2689 | { |
2688 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2690 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
2689 | cputime64_t cputime64 = cputime_to_cputime64(cputime); | 2691 | u64 cputime64 = cputime_to_cputime64(cputime); |
2690 | struct rq *rq = this_rq(); | 2692 | struct rq *rq = this_rq(); |
2691 | 2693 | ||
2692 | if (atomic_read(&rq->nr_iowait) > 0) | 2694 | if (atomic_read(&rq->nr_iowait) > 0) |
2693 | cpustat->iowait = cputime64_add(cpustat->iowait, cputime64); | 2695 | cpustat[CPUTIME_IOWAIT] += cputime64; |
2694 | else | 2696 | else |
2695 | cpustat->idle = cputime64_add(cpustat->idle, cputime64); | 2697 | cpustat[CPUTIME_IDLE] += cputime64; |
2696 | } | 2698 | } |
2697 | 2699 | ||
2698 | static __always_inline bool steal_account_process_tick(void) | 2700 | static __always_inline bool steal_account_process_tick(void) |
@@ -2742,16 +2744,16 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick, | |||
2742 | struct rq *rq) | 2744 | struct rq *rq) |
2743 | { | 2745 | { |
2744 | cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); | 2746 | cputime_t one_jiffy_scaled = cputime_to_scaled(cputime_one_jiffy); |
2745 | cputime64_t tmp = cputime_to_cputime64(cputime_one_jiffy); | 2747 | u64 tmp = cputime_to_cputime64(cputime_one_jiffy); |
2746 | struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; | 2748 | u64 *cpustat = kcpustat_this_cpu->cpustat; |
2747 | 2749 | ||
2748 | if (steal_account_process_tick()) | 2750 | if (steal_account_process_tick()) |
2749 | return; | 2751 | return; |
2750 | 2752 | ||
2751 | if (irqtime_account_hi_update()) { | 2753 | if (irqtime_account_hi_update()) { |
2752 | cpustat->irq = cputime64_add(cpustat->irq, tmp); | 2754 | cpustat[CPUTIME_IRQ] += tmp; |
2753 | } else if (irqtime_account_si_update()) { | 2755 | } else if (irqtime_account_si_update()) { |
2754 | cpustat->softirq = cputime64_add(cpustat->softirq, tmp); | 2756 | cpustat[CPUTIME_SOFTIRQ] += tmp; |
2755 | } else if (this_cpu_ksoftirqd() == p) { | 2757 | } else if (this_cpu_ksoftirqd() == p) { |
2756 | /* | 2758 | /* |
2757 | * ksoftirqd time do not get accounted in cpu_softirq_time. | 2759 | * ksoftirqd time do not get accounted in cpu_softirq_time. |
@@ -2759,7 +2761,7 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick, | |||
2759 | * Also, p->stime needs to be updated for ksoftirqd. | 2761 | * Also, p->stime needs to be updated for ksoftirqd. |
2760 | */ | 2762 | */ |
2761 | __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, | 2763 | __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, |
2762 | &cpustat->softirq); | 2764 | CPUTIME_SOFTIRQ); |
2763 | } else if (user_tick) { | 2765 | } else if (user_tick) { |
2764 | account_user_time(p, cputime_one_jiffy, one_jiffy_scaled); | 2766 | account_user_time(p, cputime_one_jiffy, one_jiffy_scaled); |
2765 | } else if (p == rq->idle) { | 2767 | } else if (p == rq->idle) { |
@@ -2768,7 +2770,7 @@ static void irqtime_account_process_tick(struct task_struct *p, int user_tick, | |||
2768 | account_guest_time(p, cputime_one_jiffy, one_jiffy_scaled); | 2770 | account_guest_time(p, cputime_one_jiffy, one_jiffy_scaled); |
2769 | } else { | 2771 | } else { |
2770 | __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, | 2772 | __account_system_time(p, cputime_one_jiffy, one_jiffy_scaled, |
2771 | &cpustat->system); | 2773 | CPUTIME_SYSTEM); |
2772 | } | 2774 | } |
2773 | } | 2775 | } |
2774 | 2776 | ||