public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: Dave Chinner <david@fromorbit.com>
Cc: Brian Foster <bfoster@redhat.com>, linux-xfs@vger.kernel.org
Subject: Re: lockdep recursive locking warning on for-next
Date: Thu, 18 Feb 2021 20:28:33 -0800	[thread overview]
Message-ID: <20210219042833.GA7193@magnolia> (raw)
In-Reply-To: <20210219041427.GE4662@dread.disaster.area>

On Fri, Feb 19, 2021 at 03:14:27PM +1100, Dave Chinner wrote:
> On Thu, Feb 18, 2021 at 11:31:54AM -0800, Darrick J. Wong wrote:
> > On Thu, Feb 18, 2021 at 02:12:52PM -0500, Brian Foster wrote:
> > > On Thu, Feb 18, 2021 at 10:49:26AM -0800, Darrick J. Wong wrote:
> > > > On Thu, Feb 18, 2021 at 01:14:50PM -0500, Brian Foster wrote:
> > > > > Hi Darrick,
> > > > > 
> > > > > I'm seeing the warning below via xfs/167 on a test machine. It looks
> > > > > like it's just complaining about nested freeze protection between the
> > > > > scan invocation and an underlying transaction allocation for an inode
> > > > > eofblocks trim. I suppose we could either refactor xfs_trans_alloc() to
> > > > > drop and reacquire freeze protection around the scan, or alternatively
> > > > > call __sb_writers_release() and __sb_writers_acquire() around the scan
> > > > > to retain freeze protection and quiet lockdep. Hm?
> > > > 
> > > > Erk, isn't that a potential log grant livelock too?
> > > > 
> > > > Fill up the filesystem with real data and cow blocks until it's full,
> > > > then spawn exactly enough file writer threads to eat up all the log
> > > > reservation, then each _reserve() fails, so every thread starts a scan
> > > > and tries to allocate /another/ transaction ... but there's no space
> > > > left in the log, so those scans just block indefinitely.
> > > > 
> > > > So... I think the solution here is to go back to a previous version of
> > > > what that patchset did, where we'd drop the whole transaction, run the
> > > > scan, and jump back to the top of the function to get a fresh
> > > > transaction.
> > > > 
> > > 
> > > But we don't call into the scan while holding log reservation. We hold
> > > the transaction memory and freeze protection. It's probably debatable
> > > whether we'd want to scan with freeze protection held or not, but I
> > > don't see how dropping either of those changes anything wrt to log
> > > reservation..?
> > 
> > Right, sorry about the noise.  We could just trick lockdep with
> > __sb_writers_release like you said.  Though I am a tad bit concerned
> > about the rwsem behavior -- what happens if:
> > 
> > T1 calls sb_start_intwrite (which is down_read on sb_writers), gets the
> > lock, and then hits ENOSPC and goes into our scan loop; meanwhile,
> > 
> > T2 calls sb_wait_write (which is down_write on sb_writers), and is
> > scheduled off because it was a blocking lock attempt; and then,
> > 
> > T1 finds some eofblocks to delete, and now it wants to sb_start_intwrite
> > again as part of allocating that second nested transaction.  Does that
> > actually work, or will T1 stall because we don't allow more readers once
> > something is waiting in down_write()?
> 
> The stack trace nesting inside xfs_trans_alloc() looks fundamentally
> wrong to me. It screams "warning, dragons be here" to me. We're not
> allowed to nest transactions -anywhere- so actually designing a call
> path that ends up looking like we are nesting transactions but then
> plays whacky games to avoid problems associated with nesting
> seems... poorly thought out.

The original version of the code[1] in question cancelled the
transaction before starting the scan, but the reviewers didn't think it
would be a problem to hold on to the transaction or recurse intwrite.

[1] https://lore.kernel.org/linux-xfs/20210124094816.GE670331@infradead.org/

I probably should've just kept it the way it was.  Well, maybe I'll send
in my own fixpatch and see what the rest of you think.

> > > > > BTW, the stack report also had me wondering whether we had or need any
> > > > > nesting protection in these new scan invocations. For example, if we
> > > > > have an fs with a bunch of tagged inodes and concurrent allocation
> > > > > activity, would anything prevent an in-scan transaction allocation from
> > > > > jumping back into the scan code to complete outstanding work? It looks
> > > > > like that might not be possible right now because neither scan reserves
> > > > > blocks, but they do both use transactions and that's quite a subtle
> > > > > balance..
> > > > 
> > > > Yes, that's a subtlety that screams for better documentation.
> > > > 
> > > 
> > > TBH, I'm not sure that's enough. I think we should at least have some
> > > kind of warning, even if only in DEBUG mode, that explicitly calls out
> > > if we've become susceptible to this kind of scan reentry. Otherwise I
> > > suspect that if this problem is ever truly introduced, the person who
> > > first discovers it will probably be user with a blown stack. :( Could we
> > > set a flag on the task or something that warns as such (i.e. "WARNING:
> > > attempted block reservation in block reclaim context") or perhaps just
> > > prevents scan reentry in the first place?
> > 
> > What if we implemented a XFS_TRANS_TRYRESERVE flag that would skip the
> > scanning loops?  Then it would be at least a little more obvious when
> > xfs_free_eofblocks and xfs_reflink_cancel_cow_range kick on.
> 
> Isn't detecting transaction reentry exactly what PF_FSTRANS is for?
> 
> Or have we dropped that regression fix on the ground *again*?

That series isn't making progress.

--D

> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> david@fromorbit.com

  reply	other threads:[~2021-02-19  4:29 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-18 18:14 lockdep recursive locking warning on for-next Brian Foster
2021-02-18 18:49 ` Darrick J. Wong
2021-02-18 19:12   ` Brian Foster
2021-02-18 19:31     ` Darrick J. Wong
2021-02-18 20:26       ` Brian Foster
2021-02-19  4:14       ` Dave Chinner
2021-02-19  4:28         ` Darrick J. Wong [this message]
2021-02-19  5:48           ` Dave Chinner
2021-02-22 22:53             ` Dave Chinner

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=20210219042833.GA7193@magnolia \
    --to=djwong@kernel.org \
    --cc=bfoster@redhat.com \
    --cc=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.org \
    /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