Skip to content

Commit 2d02cc1

Browse files
Zeng Jiahaoshiloong
authored andcommitted
anolis: sched: fix race condition when adjust guest cputime
ANBZ: torvalds#394 Cpuacct.proc_stat_show callback will read cpuacct's per-cpu kcpustat by `per_cpu_ptr`. the `kcpustats` is not protected by any lock. When adjust guest cputime, it will subtract tick_user by tick_guest. In a extreme case, the tick_user version is older than tick_guest, if the tick_guest value close the tick_user, the result will be negative. cpu0 | cpu1 __cpuacct_get_usage_result: | per_cpu_ptr(ca->cpustat, 1); | read tick_user | | update tick_user and tick_guest read tick_guest | tick_user - tick_guest | Fixes: a1bc632 (anolis: cpuacct: fix guest cgroup usage more than user usage) Signed-off-by: Zeng Jiahao <[email protected]> Reviewed-by: Shanpei Chen <[email protected]>
1 parent b348c22 commit 2d02cc1

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

kernel/sched/cpuacct.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -981,8 +981,13 @@ static void __cpuacct_get_usage_result(struct cpuacct *ca, int cpu,
981981
tick_sys = kcpustat->cpustat[CPUTIME_SYSTEM];
982982
tick_irq = kcpustat->cpustat[CPUTIME_IRQ];
983983
tick_softirq = kcpustat->cpustat[CPUTIME_SOFTIRQ];
984-
tick_guest = kcpustat->cpustat[CPUTIME_GUEST];
985-
tick_guest_nice = kcpustat->cpustat[CPUTIME_GUEST_NICE];
984+
/* Typically, the tick_guest should be small or equal than tick_user.
985+
* But the kcpustat could be read/wrote parallelism, the tick_guest may
986+
* newer than tick_user, which will cause the `tick_user - tick_guest`
987+
* become negative
988+
*/
989+
tick_guest = min(tick_user, kcpustat->cpustat[CPUTIME_GUEST]);
990+
tick_guest_nice = min(tick_nice, kcpustat->cpustat[CPUTIME_GUEST_NICE]);
986991

987992
/* Calculate system run time */
988993
cputime.sum_exec_runtime = cpuusage->usages[CPUACCT_STAT_USER] +

0 commit comments

Comments
 (0)