public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Eric Sandeen <sandeen@sandeen.net>
To: Dave Chinner <david@fromorbit.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH] xfs: prevent deadlock trying to cover an active log
Date: Thu, 10 Oct 2013 22:23:46 -0500	[thread overview]
Message-ID: <52576F42.7070501@sandeen.net> (raw)
In-Reply-To: <20131010214227.GA4446@dastard>

On 10/10/13 4:42 PM, Dave Chinner wrote:
> On Thu, Oct 10, 2013 at 12:05:46PM -0500, Eric Sandeen wrote:
>> On 10/8/13 7:31 PM, Dave Chinner wrote:
>>> From: Dave Chinner <dchinner@redhat.com>
>>>
>>> Recent analysis of a deadlocked XFS filesystem from a kernel
>>> crash dump indicated that the filesystem was stuck waiting for log
>>> space. The short story of the hang on the RHEL6 kernel is this:
>>>
>>> 	- the tail of the log is pinned by an inode
>>> 	- the inode has been pushed by the xfsaild
>>> 	- the inode has been flushed to it's backing buffer and is
>>> 	  currently flush locked and hence waiting for backing
>>> 	  buffer IO to complete and remove it from the AIL
>>> 	- the backing buffer is marked for write - it is on the
>>> 	  delayed write queue
>>> 	- the inode buffer has been modified directly and logged
>>> 	  recently due to unlinked inode list modification
>>> 	- the backing buffer is pinned in memory as it is in the
>>> 	  active CIL context.
>>> 	- the xfsbufd won't start buffer writeback because it is
>>> 	  pinned
>>> 	- xfssyncd won't force the log because it sees the log as
>>> 	  needing to be covered and hence wants to issue a dummy
>>> 	  transaction to move the log covering state machine along.
>>>
>>> Hence there is no trigger to force the CIL to the log and hence
>>> unpin the inode buffer and therefore complete the inode IO, remove
>>> it from the AIL and hence move the tail of the log along, allowing
>>> transactions to start again.
> ....
>>>  int
>>>  xfs_log_need_covered(xfs_mount_t *mp)
>>>  {
>>> -	int		needed = 0;
>>>  	struct xlog	*log = mp->m_log;
>>> +	int		needed = 0;
>>>  
>>>  	if (!xfs_fs_writable(mp))
>>>  		return 0;
>>>  
>>> +	if (!xlog_cil_empty(log))
>>> +		return 0;
>>> +
>>>  	spin_lock(&log->l_icloglock);
>>>  	switch (log->l_covered_state) {
>>>  	case XLOG_STATE_COVER_DONE:
>>> @@ -1029,14 +1036,17 @@ xfs_log_need_covered(xfs_mount_t *mp)
>>
>> This hunk is all cosmetic, right?  (nice cosmetic, but cosmetic).
> 
> No, it's a logic change.
> 
>> Kinda wish this were in a patch 2/2 just for clarity.
>>
>>>  		break;
>>>  	case XLOG_STATE_COVER_NEED:
>>>  	case XLOG_STATE_COVER_NEED2:
>>> -		if (!xfs_ail_min_lsn(log->l_ailp) &&
>>> -		    xlog_iclogs_empty(log)) {
>>> -			if (log->l_covered_state == XLOG_STATE_COVER_NEED)
>>> -				log->l_covered_state = XLOG_STATE_COVER_DONE;
>>> -			else
>>> -				log->l_covered_state = XLOG_STATE_COVER_DONE2;
>>> -		}
>>> -		/* FALLTHRU */
>>> +		if (xfs_ail_min_lsn(log->l_ailp))
>>> +			break;
>>> +		if (!xlog_iclogs_empty(log))
>>> +			break;
>>> +
>>> +		needed = 1;
>>> +		if (log->l_covered_state == XLOG_STATE_COVER_NEED)
>>> +			log->l_covered_state = XLOG_STATE_COVER_DONE;
>>> +		else
>>> +			log->l_covered_state = XLOG_STATE_COVER_DONE2;
>>> +		break;
>>>  	default:
>>>  		needed = 1;
>>>  		break;
> 
> There is different logic - the old code *always* fell through to set
> needed = 1, regardless of whether the AIL or iclogs had anything in
> them or not. Hence we'd try to cover the log when we clearly could
> not make any progress covering it and so we make a transaction
> reservation when in a state that could potentially deadlock.
> 
> The new code only sets needed = 1 if the AIL and iclogs are empty
> and so we know that covering can make progress, and hence we don't
> take a transaction reservation in the situation where the AIL is
> full and we have to block waiting for the AIL to make progress.
> Instead, the caller (xfs_log_worker) will issue a log force that
> will resolve the deadlock described above.

woof, you're right.  Ok, I misread the patch, sorry.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2013-10-11  3:23 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-09  0:31 [PATCH] xfs: prevent deadlock trying to cover an active log Dave Chinner
2013-10-10 17:05 ` Eric Sandeen
2013-10-10 21:42   ` Dave Chinner
2013-10-11  3:23     ` Eric Sandeen [this message]
2013-10-11  3:40 ` Eric Sandeen
2013-10-14 20:04   ` Ben Myers
2013-10-14 20:22     ` Dave Chinner
2013-10-14 20:36       ` Ben Myers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52576F42.7070501@sandeen.net \
    --to=sandeen@sandeen.net \
    --cc=david@fromorbit.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox