Patch from Trond Myklebust Tofix the mmap oom lockup. The actual reception of the reply is done by a softirq, however rpciod itself has to handle teardown of the asynchronous request. rpciod hangs can be prevented for the case of 'rpc_malloc' by simply making it always GFP_ATOMIC. The problem is when rpciod wants to transmit through the socket: we could set sk->allocation to GFP_ATOMIC, but there are no memory pools there to bail us out... net/sunrpc/clnt.c | 3 +-- net/sunrpc/sched.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff -puN net/sunrpc/clnt.c~rpciod-atomic-allocations net/sunrpc/clnt.c --- 25/net/sunrpc/clnt.c~rpciod-atomic-allocations 2003-03-08 21:51:27.000000000 -0800 +++ 25-akpm/net/sunrpc/clnt.c 2003-03-08 21:51:27.000000000 -0800 @@ -514,10 +514,9 @@ call_allocate(struct rpc_task *task) if (rpc_malloc(task, bufsiz << 1) != NULL) return; - printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); + dprintk("RPC: buffer allocation failed for task %p\n", task); if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) { - xprt_release(task); task->tk_action = call_reserve; rpc_delay(task, HZ>>4); return; diff -puN net/sunrpc/sched.c~rpciod-atomic-allocations net/sunrpc/sched.c --- 25/net/sunrpc/sched.c~rpciod-atomic-allocations 2003-03-08 21:51:27.000000000 -0800 +++ 25-akpm/net/sunrpc/sched.c 2003-03-08 21:51:27.000000000 -0800 @@ -672,7 +672,7 @@ rpc_malloc(struct rpc_task *task, size_t { int gfp; - if (task->tk_flags & RPC_TASK_SWAPPER) + if (task->tk_flags & (RPC_TASK_SWAPPER|RPC_TASK_ASYNC)) gfp = GFP_ATOMIC; else gfp = GFP_NOFS; _