diff options
author | Arnd Bergmann <arnd@arndb.de> | 2012-01-07 12:30:20 +0000 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-01-07 12:42:17 +0000 |
commit | 237c78beb8a988453bac1993d21f025d070a0d8d (patch) | |
tree | 9864f0924650770881141359a2d5bac623949789 /kernel/futex.c | |
parent | 4eb821999086417ab42a15174b51497122fc406e (diff) | |
parent | 7b9dd47136c07ffd883aff6926c7b281e4c1eea4 (diff) |
Merge branch 'depends/rmk/for-linus' into samsung/dt
Conflicts:
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/cpu.c -> common.c
arch/arm/mach-exynos/include/mach/entry-macro.S
arch/arm/mach-exynos/init.c -> common.c
arch/arm/mach-s5p64x0/init.c -> common.c
arch/arm/mach-s5pv210/init.c -> common.c
Multiple files were moved into common.c files in the rmk/for-linus
branch, so this moves over the samsung/dt changes to the new
files.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'kernel/futex.c')
-rw-r--r-- | kernel/futex.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index ea87f4d2f45..1614be20173 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -314,17 +314,29 @@ again: #endif lock_page(page_head); + + /* + * If page_head->mapping is NULL, then it cannot be a PageAnon + * page; but it might be the ZERO_PAGE or in the gate area or + * in a special mapping (all cases which we are happy to fail); + * or it may have been a good file page when get_user_pages_fast + * found it, but truncated or holepunched or subjected to + * invalidate_complete_page2 before we got the page lock (also + * cases which we are happy to fail). And we hold a reference, + * so refcount care in invalidate_complete_page's remove_mapping + * prevents drop_caches from setting mapping to NULL beneath us. + * + * The case we do have to guard against is when memory pressure made + * shmem_writepage move it from filecache to swapcache beneath us: + * an unlikely race, but we do need to retry for page_head->mapping. + */ if (!page_head->mapping) { + int shmem_swizzled = PageSwapCache(page_head); unlock_page(page_head); put_page(page_head); - /* - * ZERO_PAGE pages don't have a mapping. Avoid a busy loop - * trying to find one. RW mapping would have COW'd (and thus - * have a mapping) so this page is RO and won't ever change. - */ - if ((page_head == ZERO_PAGE(address))) - return -EFAULT; - goto again; + if (shmem_swizzled) + goto again; + return -EFAULT; } /* |