[PATCH v4.4-rc7] sched: isolate task_struct bitfields according to synchronization domains

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 from this list: send the line "unsubscribe cgroups" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux