From: Chris Wright Date: Tue, 23 May 2006 01:52:00 +0000 (-0700) Subject: cpuset might sleep fix from Paul Jackson X-Git-Tag: v2.6.16.19~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b4eab74ba11b4d74356ae38aaaa367f808f37534;p=thirdparty%2Fkernel%2Fstable-queue.git cpuset might sleep fix from Paul Jackson --- 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 index 00000000000..e19170be282 --- /dev/null +++ b/queue-2.6.16/cpuset-might-sleep-checking-zones-allowed-fix.patch @@ -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 +To: stable@kernel.org +Cc: Paul Jackson , David Chinner , Simon.Derr@bull.net +Subject: Cpuset: might sleep checking zones allowed fix + +From: Paul Jackson + +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 +Signed-off-by: Chris Wright +--- + + 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 diff --git a/queue-2.6.16/series b/queue-2.6.16/series index b574cca059f..1e4f67d1b38 100644 --- a/queue-2.6.16/series +++ b/queue-2.6.16/series @@ -1,2 +1,3 @@ altix-correct-ioc4-port-order.patch altix-correct-ioc3-port-order.patch +cpuset-might-sleep-checking-zones-allowed-fix.patch