Re: [Bugme-new] [Bug 15709] New: swapper page allocation failure

From: Trond Myklebust
Date: Mon Apr 26 2010 - 19:29:12 EST


On Tue, 2010-04-27 at 00:18 +0200, Robert Wimmer wrote:
> > Sure. In addition to what you did above, please do
> >
> > mount -t debugfs none /sys/kernel/debug
> >
> > and then cat the contents of the pseudofile at
> >
> > /sys/kernel/debug/tracing/stack_trace
> >
> > Please do this more or less immediately after you've finished mounting
> > the NFSv4 client.
> >
>
> I've uploaded the stack trace. It was generated
> directly after mounting. Here are the stacks:
>
> After mounting:
> https://bugzilla.kernel.org/attachment.cgi?id=26153
> After the soft lockup:
> https://bugzilla.kernel.org/attachment.cgi?id=26154
> The dmesg output of the soft lockup:
> https://bugzilla.kernel.org/attachment.cgi?id=26155
>
> > Does your server have the 'crossmnt' or 'nohide' flags set, or does it
> > use the 'refer' export option anywhere? If so, then we might have to
> > test further, since those may trigger the NFSv4 submount feature.
> >
> The server has the following settings:
> rw,nohide,insecure,async,no_subtree_check,no_root_squash
>
> Thanks!
> Robert
>
>

That second trace is more than 5.5K deep, more than half of which is
socket overhead :-(((.

The process stack does not appear to have overflowed, however that trace
doesn't include any IRQ stack overhead.

OK... So what happens if we get rid of half of that trace by forcing
asynchronous tasks such as this to run entirely in rpciod instead of
first trying to run in the process context?

See the attachment...
SUNRPC: Reduce asynchronous RPC task stack usage

From: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>

We should just farm out asynchronous RPC tasks immediately to rpciod...

Signed-off-by: Trond Myklebust <Trond.Myklebust@xxxxxxxxxx>
---

net/sunrpc/sched.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)


diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index c8979ce..22a097f 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -720,7 +720,12 @@ void rpc_execute(struct rpc_task *task)
{
rpc_set_active(task);
rpc_set_running(task);
- __rpc_execute(task);
+ if (RPC_IS_ASYNC(task)) {
+ INIT_WORK(&task->u.tk_work, rpc_async_schedule);
+ queue_work(rpciod_workqueue, &task->u.tk_work);
+
+ } else
+ __rpc_execute(task);
}

static void rpc_async_schedule(struct work_struct *work)