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>
This commit is contained in:
Родитель
e65805251f
Коммит
784bdf3bb6
|
@ -179,7 +179,15 @@ int __read_mostly futex_cmpxchg_enabled;
|
||||||
* Futex flags used to encode options to functions and preserve them across
|
* Futex flags used to encode options to functions and preserve them across
|
||||||
* restarts.
|
* restarts.
|
||||||
*/
|
*/
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
# define FLAGS_SHARED 0x01
|
# define FLAGS_SHARED 0x01
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* NOMMU does not have per process address space. Let the compiler optimize
|
||||||
|
* code away.
|
||||||
|
*/
|
||||||
|
# define FLAGS_SHARED 0x00
|
||||||
|
#endif
|
||||||
#define FLAGS_CLOCKRT 0x02
|
#define FLAGS_CLOCKRT 0x02
|
||||||
#define FLAGS_HAS_TIMEOUT 0x04
|
#define FLAGS_HAS_TIMEOUT 0x04
|
||||||
|
|
||||||
|
@ -405,6 +413,16 @@ static void get_futex_key_refs(union futex_key *key)
|
||||||
if (!key->both.ptr)
|
if (!key->both.ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On MMU less systems futexes are always "private" as there is no per
|
||||||
|
* process address space. We need the smp wmb nevertheless - yes,
|
||||||
|
* arch/blackfin has MMU less SMP ...
|
||||||
|
*/
|
||||||
|
if (!IS_ENABLED(CONFIG_MMU)) {
|
||||||
|
smp_mb(); /* explicit smp_mb(); (B) */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
|
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
|
||||||
case FUT_OFF_INODE:
|
case FUT_OFF_INODE:
|
||||||
ihold(key->shared.inode); /* implies smp_mb(); (B) */
|
ihold(key->shared.inode); /* implies smp_mb(); (B) */
|
||||||
|
@ -436,6 +454,9 @@ static void drop_futex_key_refs(union futex_key *key)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!IS_ENABLED(CONFIG_MMU))
|
||||||
|
return;
|
||||||
|
|
||||||
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
|
switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
|
||||||
case FUT_OFF_INODE:
|
case FUT_OFF_INODE:
|
||||||
iput(key->shared.inode);
|
iput(key->shared.inode);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче