]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
cpuset might sleep fix from Paul Jackson
authorChris Wright <chrisw@sous-sol.org>
Tue, 23 May 2006 01:52:00 +0000 (18:52 -0700)
committerChris Wright <chrisw@sous-sol.org>
Tue, 23 May 2006 01:52:00 +0000 (18:52 -0700)
queue-2.6.16/cpuset-might-sleep-checking-zones-allowed-fix.patch [new file with mode: 0644]
queue-2.6.16/series

diff --git a/queue-2.6.16/cpuset-might-sleep-checking-zones-allowed-fix.patch b/queue-2.6.16/cpuset-might-sleep-checking-zones-allowed-fix.patch
new file mode 100644 (file)
index 0000000..e19170b
--- /dev/null
@@ -0,0 +1,67 @@
+From stable-bounces@linux.kernel.org  Mon May 22 18:00:14 2006
+Date: Mon, 22 May 2006 17:56:07 -0700
+From: Paul Jackson <pj@sgi.com>
+To: stable@kernel.org
+Cc: Paul Jackson <pj@sgi.com>, David Chinner <dgc@sgi.com>, Simon.Derr@bull.net
+Subject: Cpuset: might sleep checking zones allowed fix
+
+From: Paul Jackson <pj@sgi.com>
+
+Fix an infrequently encountered 'sleeping function called
+from invalid context' in the cpuset hooks in __alloc_pages.
+Could sleep while interrupts disabled.
+
+The routine cpuset_zone_allowed() is called by code in
+mm/page_alloc.c __alloc_pages() to determine if a zone is
+allowed in the current tasks cpuset.  This routine can sleep,
+for certain GFP_KERNEL allocations, if the zone is on a memory
+node not allowed in the current cpuset, but might be allowed
+in a parent cpuset.
+
+But we can't sleep in __alloc_pages() if in interrupt, nor
+if called for a GFP_ATOMIC request (__GFP_WAIT not set in
+gfp_flags).
+
+The rule was intended to be:
+  Don't call cpuset_zone_allowed() if you can't sleep, unless you
+  pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
+  the code that might scan up ancestor cpusets and sleep.
+
+This rule was being violated due to a bogus change made (by myself,
+pj) to __alloc_pages() as part of the November 2005 effort to
+cleanup its logic.
+
+The bogus change can be seen at:
+  http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-11/4691.html
+  [PATCH 01/05] mm fix __alloc_pages cpuset ALLOC_* flags
+
+This was first noticed on a tight memory system, in code that
+was disabling interrupts and doing allocation requests with
+__GFP_WAIT not set, which resulted in __might_sleep() writing
+complaints to the log "Debug: sleeping function called ...",
+when the code in cpuset_zone_allowed() tried to take the
+callback_sem cpuset semaphore.
+
+Special thanks to Dave Chinner, for figuring this out,
+and a tip of the hat to Nick Piggin who warned me of this
+back in Nov 2005, before I was ready to listen.
+
+Signed-off-by: Paul Jackson <pj@sgi.com>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ mm/page_alloc.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- linux-2.6.16.18.orig/mm/page_alloc.c
++++ linux-2.6.16.18/mm/page_alloc.c
+@@ -949,7 +949,8 @@ restart:
+               alloc_flags |= ALLOC_HARDER;
+       if (gfp_mask & __GFP_HIGH)
+               alloc_flags |= ALLOC_HIGH;
+-      alloc_flags |= ALLOC_CPUSET;
++      if (wait)
++              alloc_flags |= ALLOC_CPUSET;
+       /*
+        * Go through the zonelist again. Let __GFP_HIGH and allocations
index b574cca059f70843e3a24ee67ed3d6764d78164d..1e4f67d1b381fb0f7a0fcb43138157541f9ca996 100644 (file)
@@ -1,2 +1,3 @@
 altix-correct-ioc4-port-order.patch
 altix-correct-ioc3-port-order.patch
+cpuset-might-sleep-checking-zones-allowed-fix.patch