xfs: queue inactivation immediately when free space is tight
authorDarrick J. Wong <djwong@kernel.org>
Fri, 6 Aug 2021 18:05:40 +0000 (11:05 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 9 Aug 2021 17:52:17 +0000 (10:52 -0700)
Now that we have made the inactivation of unlinked inodes a background
task to increase the throughput of file deletions, we need to be a
little more careful about how long of a delay we can tolerate.

On a mostly empty filesystem, the risk of the allocator making poor
decisions due to fragmentation of the free space on account a lengthy
delay in background updates is minimal because there's plenty of space.
However, if free space is tight, we want to deallocate unlinked inodes
as quickly as possible to avoid fallocate ENOSPC and to give the
allocator the best shot at optimal allocations for new writes.

Therefore, queue the percpu worker immediately if the filesystem is more
than 95% full.  This follows the same principle that XFS becomes less
aggressive about speculative allocations and lazy cleanup (and more
precise about accounting) when nearing full.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/xfs_icache.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h

index 7d93edb331fb2e1b32fa27fad775f8328cfeb41f..8b2ac969c60c9389c7be031b08b94b0462c415fd 100644 (file)
@@ -1920,6 +1920,7 @@ xfs_inodegc_start(
  * Schedule the inactivation worker when:
  *
  *  - We've accumulated more than one inode cluster buffer's worth of inodes.
+ *  - There is less than 5% free space left.
  */
 static inline bool
 xfs_inodegc_want_queue_work(
@@ -1931,6 +1932,11 @@ xfs_inodegc_want_queue_work(
        if (items > mp->m_ino_geo.inodes_per_cluster)
                return true;
 
+       if (__percpu_counter_compare(&mp->m_fdblocks,
+                               mp->m_low_space[XFS_LOWSP_5_PCNT],
+                               XFS_FDBLOCKS_BATCH) < 0)
+               return true;
+
        return false;
 }
 
index 1f7e9a608f38f7807e8a38e6d15cc7a77cf079f6..5fe6f1db4fe91cce923ab479979b9252687dd77d 100644 (file)
@@ -1077,14 +1077,6 @@ xfs_fs_writable(
        return true;
 }
 
-/*
- * Deltas for the block count can vary from 1 to very large, but lock contention
- * only occurs on frequent small block count updates such as in the delayed
- * allocation path for buffered writes (page a time updates). Hence we set
- * a large batch count (1024) to minimise global counter updates except when
- * we get near to ENOSPC and we have to be very accurate with our updates.
- */
-#define XFS_FDBLOCKS_BATCH     1024
 int
 xfs_mod_fdblocks(
        struct xfs_mount        *mp,
index e6f8675e7a40006a297efa7b987030be6c1afc43..60468a2a5e67961def8c4e6527fc4e8836aa221f 100644 (file)
@@ -348,6 +348,15 @@ extern uint64_t xfs_default_resblks(xfs_mount_t *mp);
 extern int     xfs_mountfs(xfs_mount_t *mp);
 extern void    xfs_unmountfs(xfs_mount_t *);
 
+/*
+ * Deltas for the block count can vary from 1 to very large, but lock contention
+ * only occurs on frequent small block count updates such as in the delayed
+ * allocation path for buffered writes (page a time updates). Hence we set
+ * a large batch count (1024) to minimise global counter updates except when
+ * we get near to ENOSPC and we have to be very accurate with our updates.
+ */
+#define XFS_FDBLOCKS_BATCH     1024
+
 extern int     xfs_mod_fdblocks(struct xfs_mount *mp, int64_t delta,
                                 bool reserved);
 extern int     xfs_mod_frextents(struct xfs_mount *mp, int64_t delta);