diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index f96be9370b75..bae6fcfe6d75 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -8998,12 +8998,30 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime) | |||
8998 | } | 8998 | } |
8999 | 8999 | ||
9000 | /* | 9000 | /* |
9001 | * When CONFIG_VIRT_CPU_ACCOUNTING is enabled one jiffy can be very large | ||
9002 | * in cputime_t units. As a result, cpuacct_update_stats calls | ||
9003 | * percpu_counter_add with values large enough to always overflow the | ||
9004 | * per cpu batch limit causing bad SMP scalability. | ||
9005 | * | ||
9006 | * To fix this we scale percpu_counter_batch by cputime_one_jiffy so we | ||
9007 | * batch the same amount of time with CONFIG_VIRT_CPU_ACCOUNTING disabled | ||
9008 | * and enabled. We cap it at INT_MAX which is the largest allowed batch value. | ||
9009 | */ | ||
9010 | #ifdef CONFIG_SMP | ||
9011 | #define CPUACCT_BATCH \ | ||
9012 | min_t(long, percpu_counter_batch * cputime_one_jiffy, INT_MAX) | ||
9013 | #else | ||
9014 | #define CPUACCT_BATCH 0 | ||
9015 | #endif | ||
9016 | |||
9017 | /* | ||
9001 | * Charge the system/user time to the task's accounting group. | 9018 | * Charge the system/user time to the task's accounting group. |
9002 | */ | 9019 | */ |
9003 | static void cpuacct_update_stats(struct task_struct *tsk, | 9020 | static void cpuacct_update_stats(struct task_struct *tsk, |
9004 | enum cpuacct_stat_index idx, cputime_t val) | 9021 | enum cpuacct_stat_index idx, cputime_t val) |
9005 | { | 9022 | { |
9006 | struct cpuacct *ca; | 9023 | struct cpuacct *ca; |
9024 | int batch = CPUACCT_BATCH; | ||
9007 | 9025 | ||
9008 | if (unlikely(!cpuacct_subsys.active)) | 9026 | if (unlikely(!cpuacct_subsys.active)) |
9009 | return; | 9027 | return; |
@@ -9012,7 +9030,7 @@ static void cpuacct_update_stats(struct task_struct *tsk, | |||
9012 | ca = task_ca(tsk); | 9030 | ca = task_ca(tsk); |
9013 | 9031 | ||
9014 | do { | 9032 | do { |
9015 | percpu_counter_add(&ca->cpustat[idx], val); | 9033 | __percpu_counter_add(&ca->cpustat[idx], val, batch); |
9016 | ca = ca->parent; | 9034 | ca = ca->parent; |
9017 | } while (ca); | 9035 | } while (ca); |
9018 | rcu_read_unlock(); | 9036 | rcu_read_unlock(); |