mbox series

[0/2] xfs: reduce AGF hold times during fstrim operations

Message ID 20230903232923.211003-1-david@fromorbit.com (mailing list archive)
Headers show
Series xfs: reduce AGF hold times during fstrim operations | expand

Message

Dave Chinner Sept. 3, 2023, 11:29 p.m. UTC
A recent log space overflow and recovery failure was root caused to
a long running truncate blocking on the AGF and ending up pinning
the tail of the log. The filesystem then hung, the machine was
rebooted, and log recoery then refused to run because there wasn't
enough space in the log for EFI transaction reservation.

The reason the long running truncate got blocked on the AGF for so
long was that an fstrim was being run. THe underlying block device
was large and very slow (10TB ceph rbd volume) and so discarding all
the free space in the AG took a really long time.

The current fstrim implementation holds the AGF across the entire
operations - both the freee space scan and the issuing of all the
discards. The discards are synchronous and single depth, so if there
are millions of free spaces, we hold the AGF lock across millions of
discard operations.

It doesn't really need to be said that this is a Bad Thing.

THis series reworks the fstrim discard path to use the same
mechanisms as online discard. This allows discards to be issued
asynchronously without holding the AGF locked, enabling higher
discard queue depths (much faster on fast devices) and only
requiring the AGF lock to be held whilst we are scanning free space.

To do this, we make use of busy extents - we lock the AGF, mark all
the extents we want to discard as "busy under discard" so that
nothing will be allowed to allocate them, and then drop the AGF
lock. We then issue discards on the gathered busy extents and on
discard completion remove them from the busy list.

This results in AGF lock holds times for fstrim dropping to a few
milliseconds each batch of free extents we scan, and so the hours
long hold times that can currently occur on large, slow, badly
fragmented device no longer occur.

This passes fstests with '-o discard' enabled, and has run the '-g
trim' group several dozen times without any reported regressions.

-----
Version 2:
- fix various typos and formatting things
- move online discard code to fs/xfs/xfs_discard.c and make it
  generic (new patch)
- use xfs_alloc_rec_incore() as the iteration cursor
- remove hacky "keep gathering until size changes" batching code now
  that cursor can restart at an exact extent
- rework fstrim iteration to use new shared discard code

RFC:
- https://lore.kernel.org/linux-xfs/20230829065710.938039-1-david@fromorbit.com/