aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-07-29 10:32:30 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-07-29 12:44:14 -0400
commit784bdf3bb694b256fcd6120b93e8947a84249a3a (patch)
treecac56fdf1567db581d4f2a504dac6e75f878978d
parente65805251f2db69c9f67ed8062ab82526be5a374 (diff)
futex: Assume all mappings are private on !MMU systems
To quote Rick why there is no need for shared mapping on !MMU systems: |With MMU, shared futex keys need to identify the physical backing for |a memory address because it may be mapped at different addresses in |different processes (or even multiple times in the same process). |Without MMU this cannot happen. You only have physical addresses. So |the "private futex" behavior of using the virtual address as the key |is always correct (for both shared and private cases) on nommu |systems. This patch disables the FLAGS_SHARED in a way that allows the compiler to remove that code. [bigeasy: Added changelog ] Reported-by: Rich Felker <dalias@libc.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/20160729143230.GA21715@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--kernel/futex.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 33664f70e2d2..46cb3a301bc1 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -179,7 +179,15 @@ int __read_mostly futex_cmpxchg_enabled;
179 * Futex flags used to encode options to functions and preserve them across 179 * Futex flags used to encode options to functions and preserve them across
180 * restarts. 180 * restarts.
181 */ 181 */
182#define FLAGS_SHARED 0x01 182#ifdef CONFIG_MMU
183# define FLAGS_SHARED 0x01
184#else
185/*
186 * NOMMU does not have per process address space. Let the compiler optimize
187 * code away.
188 */
189# define FLAGS_SHARED 0x00
190#endif
183#define FLAGS_CLOCKRT 0x02 191#define FLAGS_CLOCKRT 0x02
184#define FLAGS_HAS_TIMEOUT 0x04 192#define FLAGS_HAS_TIMEOUT 0x04
185 193
@@ -405,6 +413,16 @@ static void get_futex_key_refs(union futex_key *key)
405 if (!key->both.ptr) 413 if (!key->both.ptr)
406 return; 414 return;
407 415
416 /*
417 * On MMU less systems futexes are always "private" as there is no per
418 * process address space. We need the smp wmb nevertheless - yes,
419 * arch/blackfin has MMU less SMP ...
420 */
421 if (!IS_ENABLED(CONFIG_MMU)) {
422 smp_mb(); /* explicit smp_mb(); (B) */
423 return;
424 }
425
408 switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { 426 switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
409 case FUT_OFF_INODE: 427 case FUT_OFF_INODE:
410 ihold(key->shared.inode); /* implies smp_mb(); (B) */ 428 ihold(key->shared.inode); /* implies smp_mb(); (B) */
@@ -436,6 +454,9 @@ static void drop_futex_key_refs(union futex_key *key)
436 return; 454 return;
437 } 455 }
438 456
457 if (!IS_ENABLED(CONFIG_MMU))
458 return;
459
439 switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { 460 switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
440 case FUT_OFF_INODE: 461 case FUT_OFF_INODE:
441 iput(key->shared.inode); 462 iput(key->shared.inode);