Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

futex: Fix uninterruptible loop due to gate_area

It was found (by Sasha) that if you use a futex located in the gate
area we get stuck in an uninterruptible infinite loop, much like the
ZERO_PAGE issue.

While looking at this problem, PeterZ realized you'll get into similar
trouble when hitting any install_special_pages() mapping. And are there
still drivers setting up their own special mmaps without page->mapping,
and without special VM or pte flags to make get_user_pages fail?

In most cases, if page->mapping is NULL, we do not need to retry at all:
Linus points out that even /proc/sys/vm/drop_caches poses no problem,
because it ends up using remove_mapping(), which takes care not to
interfere when the page reference count is raised.

But there is still one case which does need a retry: if memory pressure
called shmem_writepage in between get_user_pages_fast dropping page
table lock and our acquiring page lock, then the page gets switched from
filecache to swapcache (and ->mapping set to NULL) whatever the refcount.
Fault it back in to get the page->mapping needed for key->shared.inode.

Reported-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Hugh Dickins and committed by
Linus Torvalds
e6780f72 06867fbb

+20 -8
+20 -8
kernel/futex.c
··· 314 314 #endif 315 315 316 316 lock_page(page_head); 317 + 318 + /* 319 + * If page_head->mapping is NULL, then it cannot be a PageAnon 320 + * page; but it might be the ZERO_PAGE or in the gate area or 321 + * in a special mapping (all cases which we are happy to fail); 322 + * or it may have been a good file page when get_user_pages_fast 323 + * found it, but truncated or holepunched or subjected to 324 + * invalidate_complete_page2 before we got the page lock (also 325 + * cases which we are happy to fail). And we hold a reference, 326 + * so refcount care in invalidate_complete_page's remove_mapping 327 + * prevents drop_caches from setting mapping to NULL beneath us. 328 + * 329 + * The case we do have to guard against is when memory pressure made 330 + * shmem_writepage move it from filecache to swapcache beneath us: 331 + * an unlikely race, but we do need to retry for page_head->mapping. 332 + */ 317 333 if (!page_head->mapping) { 334 + int shmem_swizzled = PageSwapCache(page_head); 318 335 unlock_page(page_head); 319 336 put_page(page_head); 320 - /* 321 - * ZERO_PAGE pages don't have a mapping. Avoid a busy loop 322 - * trying to find one. RW mapping would have COW'd (and thus 323 - * have a mapping) so this page is RO and won't ever change. 324 - */ 325 - if ((page_head == ZERO_PAGE(address))) 326 - return -EFAULT; 327 - goto again; 337 + if (shmem_swizzled) 338 + goto again; 339 + return -EFAULT; 328 340 } 329 341 330 342 /*