summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Gortmaker <paul.gortmaker@windriver.com>2012-05-15 17:53:13 -0400
committerPaul Gortmaker <paul.gortmaker@windriver.com>2012-05-15 17:53:13 -0400
commitd6b2017bec9d2be76e863179d4c16aaef5f26f1d (patch)
treef9063daef4fe5f2efad4e475dc6b0715fcc02a9f
parent45212fc64302853c3b2070cc65996bcc8a34bb1f (diff)
downloadlongterm-queue-2.6.34-d6b2017bec9d2be76e863179d4c16aaef5f26f1d.tar.gz
Add additional futex patch to avoid regression.
Data from Hugh: -------- Including this commit worries me a little, because it introduces the ZERO_PAGE case which we later had to change. Though I did end up supplying the patch below, it was very much in consultation with Peter and Linus: I'm no expert on futices, and haven't followed the history of intervening patches between what you're including above and this one below (and I don't see an rw arg to get_futex_key() in latest source). I don't know: I'm not NAKking it, I'm just waving a reddish flag, and hoping that Peter will remember more, and have something more constructive to say, than I can think of at this moment. Hugh commit e6780f7243eddb133cc20ec37fa69317c218b709 Author: Hugh Dickins <hughd@google.com> Date: Sat Dec 31 11:44:01 2011 -0800 futex: Fix uninterruptible loop due to gate_area -------- See full discussion at: https://lkml.org/lkml/2012/5/15/87 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
-rw-r--r--queue/futex-Fix-uninterruptible-loop-due-to-gate_area.patch78
-rw-r--r--queue/series1
2 files changed, 79 insertions, 0 deletions
diff --git a/queue/futex-Fix-uninterruptible-loop-due-to-gate_area.patch b/queue/futex-Fix-uninterruptible-loop-due-to-gate_area.patch
new file mode 100644
index 0000000..d7e63bc
--- /dev/null
+++ b/queue/futex-Fix-uninterruptible-loop-due-to-gate_area.patch
@@ -0,0 +1,78 @@
+From f8fe91498b2a35fc6abc02bb213ca297bfcd2b2a Mon Sep 17 00:00:00 2001
+From: Hugh Dickins <hughd@google.com>
+Date: Sat, 31 Dec 2011 11:44:01 -0800
+Subject: [PATCH] futex: Fix uninterruptible loop due to gate_area
+
+commit e6780f7243eddb133cc20ec37fa69317c218b709 upstream.
+
+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>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[PG: 2.6.34 variable is page, not page_head, since it doesn't have a5b338f2]
+Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
+
+diff --git a/kernel/futex.c b/kernel/futex.c
+index 98a354d..8b467b4 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -264,17 +264,29 @@ again:
+
+ page = compound_head(page);
+ lock_page(page);
++
++ /*
++ * If page->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->mapping.
++ */
+ if (!page->mapping) {
++ int shmem_swizzled = PageSwapCache(page);
+ unlock_page(page);
+ put_page(page);
+- /*
+- * 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 == ZERO_PAGE(address)))
+- return -EFAULT;
+- goto again;
++ if (shmem_swizzled)
++ goto again;
++ return -EFAULT;
+ }
+
+ /*
+--
+1.7.9.6
+
diff --git a/queue/series b/queue/series
index 49338fe..14d01f2 100644
--- a/queue/series
+++ b/queue/series
@@ -165,6 +165,7 @@ perf-tools-do-not-look-at-.-config-for-configuration.patch
ALSA-snd_usb_caiaq-track-submitted-output-urbs.patch
ALSA-ac97-Add-HP-Compaq-dc5100-SFF-PT003AW-to-Headph.patch
futex-Fix-regression-with-read-only-mappings.patch
+futex-Fix-uninterruptible-loop-due-to-gate_area.patch
x86-32-vdso-On-system-call-restart-after-SYSENTER-us.patch
x86-UV-Remove-UV-delay-in-starting-slave-cpus.patch
drm-ttm-fix-ttm_bo_add_ttm-user-failure-path.patch