On May 20, 2013, at 2:29 PM, "Myklebust, Trond" <Trond.Myklebust@xxxxxxxxxx> wrote: > On Mon, 2013-05-20 at 14:13 -0400, andros@xxxxxxxxxx wrote: >> From: Andy Adamson <andros@xxxxxxxxxx> >> >> On a CB_RECALL the callback service thread flushes the inode using >> filemap_flush prior to scheduling the state manager thread to return the >> delegation. When pNFS is used and I/O has not yet gone to the data server >> servicing the inode, a LAYOUTGET can preceed the I/O. Unlike the async >> filemap_flush call, the LAYOUTGET must proceed to completion. >> >> If the state manager starts to recover data while the inode flush is sending >> the LAYOUTGET, a deadlock occurs as the callback service thread holds the >> single callback session slot until the flushing is done which blocks the state >> manager thread, and the state manager thread has set the session draining bit >> which puts the inode flush LAYOUTGET RPC to sleep on the forechannel slot >> table waitq. >> >> Separate the draining of the back channel from the draining of the fore channel >> by moving the NFS4_SESSION_DRAINING bit from session scope into the fore >> and back slot tables. Drain the back channel first allowing the LAYOUTGET >> call to proceed (and fail) so the callback service thread frees the callback >> slot. Then proceed with draining the forechannel. >> >> Signed-off-by: Andy Adamson <andros@xxxxxxxxxx> >> --- >> fs/nfs/callback_proc.c | 2 +- >> fs/nfs/callback_xdr.c | 2 +- >> fs/nfs/nfs4proc.c | 2 +- >> fs/nfs/nfs4session.c | 6 ++++-- >> fs/nfs/nfs4session.h | 13 ++++++++----- >> fs/nfs/nfs4state.c | 15 +++++++-------- >> 6 files changed, 22 insertions(+), 18 deletions(-) >> > >> @@ -395,12 +395,14 @@ int nfs4_setup_session_slot_tables(struct nfs4_session *ses) >> /* Fore channel */ >> tbl = &ses->fc_slot_table; >> tbl->session = ses; >> + tbl->slot_tbl_state = 0; >> status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1); >> if (status) /* -ENOMEM */ >> return status; >> /* Back channel */ >> tbl = &ses->bc_slot_table; >> tbl->session = ses; >> + tbl->slot_tbl_state = 0; >> status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0); >> if (status && tbl->slots == NULL) >> /* Fore and back channel share a connection so get > > Hi Andy, > Hi Trond > The above hunk is buggy. nfs4_setup_session_slot_tables() is called from > nfs4_proc_create_session(), so it must not reset the > NFS4_SLOT_TBL_DRAINING flag. Yes - I see. Good catch > > I'm therefore removing the above 2 lines. I've applied the rest of the > patch. > Thanks! -->Andy > Thanks! > Trond > > -- > Trond Myklebust > Linux NFS client maintainer > > NetApp > Trond.Myklebust@xxxxxxxxxx > www.netapp.com -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html