Re: Processes stuck on D state on Dual Opteron

Nick Piggin
2005-04-10T02:53:23Z

[-- Attachment #1: Type: text/plain, Size: 1325 bytes --]

Claudio Martins wrote:
> On Tuesday 05 April 2005 03:12, Andrew Morton wrote:
>
>>Claudio Martins <ctpm@rnl.ist.utl.pt> wrote:
>>
>>> While stress testing 2.6.12-rc2 on an HP DL145 I get processes stuck
>>>in D state after some time.
>>> This machine is a dual Opteron 248 with 2GB (ECC) on one node (the
>>>other node has no RAM modules plugged in, since this board works only
>>>with pairs).
>>>
>>> I was using stress (http://weather.ou.edu/~apw/projects/stress/) with
>>>the following command line:
>>>
>>> stress -v -c 20 -i 12 -m 10 -d 20
>>>

[snip]

> ------------------------------------
>
>
> Unfortunately the system Oopsed in the middle of dumping the tasks, but from
> what I can see I'm tempted to think that this might be related to the MD
> code. md2_raid1 is blocked on D state and, although not shown on the dump, I
> know from ps command that md0_raid1 (the swap partition) was also on D state
> (along with the stress processes which are responsible for hogging memory,
> and top and df). There were about 200MB swapped out, but the swap partition
> size is 1GB.
>

Looks like you may possibly have a memory allocation deadlock
(although I can't explain the NMI oops).

I would be interested to see if the following patch is of any
help to you.

Thanks,
Nick

--
SUSE Labs, Novell Inc.

[-- Attachment #2: mempool-can-fail.patch --]
[-- Type: text/plain, Size: 605 bytes --]

Index: linux-2.6/mm/mempool.c
===================================================================
--- linux-2.6.orig/mm/mempool.c 2005-03-30 10:39:51.000000000 +1000
+++ linux-2.6/mm/mempool.c 2005-03-30 10:41:29.000000000 +1000
@@ -198,7 +198,10 @@ void * mempool_alloc(mempool_t *pool, in
void *element;
unsigned long flags;
DEFINE_WAIT(wait);
- int gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO);
+ int gfp_nowait;
+
+ gfp_mask |= __GFP_NORETRY; /* don't loop in __alloc_pages */
+ gfp_nowait = gfp_mask & ~(__GFP_WAIT | __GFP_IO);

might_sleep_if(gfp_mask & __GFP_WAIT);