task_struct has a cluster of unsigned bitfields. Some are updated under scheduler locks while others are updated only by the task itself. Currently, the two classes of bitfields aren't distinguished and end up on the same word which can lead to clobbering when there are simultaneous read-modify-write attempts. While difficult to prove definitely, it's likely that the resulting inconsistency led to low frqeuency failures such as wrong memcg_may_oom state or loadavg underflow due to clobbered sched_contributes_to_load. Fix it by putting the two classes of the bitfields into separate unsigned longs. Original-patch-by: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx> Link: http://lkml.kernel.org/g/55FEC685.5010404@xxxxxxxxxx Cc: stable@xxxxxxxxxxxxxxx --- Hello, Peter, I took the patch and changed the bitfields to ulong. Thanks. include/linux/sched.h | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index edad7a4..e51464d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1455,22 +1455,25 @@ struct task_struct { /* Used for emulating ABI behavior of previous Linux versions */ unsigned int personality; - unsigned in_execve:1; /* Tell the LSMs that the process is doing an - * execve */ - unsigned in_iowait:1; - - /* Revert to default priority/policy when forking */ - unsigned sched_reset_on_fork:1; - unsigned sched_contributes_to_load:1; - unsigned sched_migrated:1; + /* scheduler bits, serialized by scheduler locks */ + unsigned long sched_reset_on_fork:1; + unsigned long sched_contributes_to_load:1; + unsigned long sched_migrated:1; + + /* force alignment to the next boundary */ + unsigned long :0; + + /* unserialized, strictly 'current' */ + unsigned long in_execve:1; /* bit to tell LSMs we're in execve */ + unsigned long in_iowait:1; #ifdef CONFIG_MEMCG - unsigned memcg_may_oom:1; + unsigned long memcg_may_oom:1; #endif #ifdef CONFIG_MEMCG_KMEM - unsigned memcg_kmem_skip_account:1; + unsigned long memcg_kmem_skip_account:1; #endif #ifdef CONFIG_COMPAT_BRK - unsigned brk_randomized:1; + unsigned long brk_randomized:1; #endif unsigned long atomic_flags; /* Flags needing atomic access. */ -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>