Re: [PATCH 1/1] NFSv4.1 Fix a pNFS session draining deadlock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux