diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-25 17:14:49 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-10-26 18:32:19 -0700 |
commit | 7a1cdff59c0a4d4804351f3b281010ff709994e6 (patch) | |
tree | ae4d0f580b990c68b327e7d06cc0a56401226a4a /fs/xfs/xfs_icache.c | |
parent | 95b8ab455f9c5ba4c7a33c806f1bece801e132e8 (diff) |
xfs: parallelize block preallocation garbage collectioneofblocks-consolidation_2020-10-26
Split the block preallocation garbage collection work into per-AG work
items so that we can take advantage of parallelization.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_icache.c')
-rw-r--r-- | fs/xfs/xfs_icache.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 30f8faa86dbd..ab70556dc13e 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -948,12 +948,12 @@ xfs_inode_walk( */ static void xfs_queue_blockgc( - struct xfs_mount *mp) + struct xfs_perag *pag) { rcu_read_lock(); - if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCK_GC_TAG)) - queue_delayed_work(mp->m_blockgc_workqueue, - &mp->m_blockgc_work, + if (radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_BLOCK_GC_TAG)) + queue_delayed_work(pag->pag_mount->m_blockgc_workqueue, + &pag->pag_blockgc_work, msecs_to_jiffies(xfs_blockgc_secs * 1000)); rcu_read_unlock(); } @@ -988,25 +988,40 @@ void xfs_blockgc_worker( struct work_struct *work) { - struct xfs_mount *mp = container_of(to_delayed_work(work), - struct xfs_mount, m_blockgc_work); + struct xfs_perag *pag = container_of(to_delayed_work(work), + struct xfs_perag, pag_blockgc_work); int error; - if (!sb_start_write_trylock(mp->m_super)) + if (!sb_start_write_trylock(pag->pag_mount->m_super)) return; - error = xfs_blockgc_scan(mp, NULL); + + error = xfs_inode_walk_ag(pag, 0, xfs_blockgc_scan_inode, NULL, + XFS_ICI_BLOCK_GC_TAG); if (error) - xfs_info(mp, "preallocation gc worker failed, err=%d", error); - sb_end_write(mp->m_super); - xfs_queue_blockgc(mp); + xfs_info(pag->pag_mount, + "AG %u preallocation gc worker failed, err=%d", + pag->pag_agno, error); + sb_end_write(pag->pag_mount->m_super); + xfs_queue_blockgc(pag); } +#define for_each_perag_tag(mp, next_agno, pag, tag) \ + for ((next_agno) = 0, (pag) = xfs_perag_get_tag((mp), 0, (tag)); \ + (pag) != NULL; \ + (next_agno) = (pag)->pag_agno + 1, \ + xfs_perag_put(pag), \ + (pag) = xfs_perag_get_tag((mp), (next_agno), (tag))) + /* Disable post-EOF and CoW block auto-reclamation. */ void xfs_blockgc_stop( struct xfs_mount *mp) { - cancel_delayed_work_sync(&mp->m_blockgc_work); + struct xfs_perag *pag; + xfs_agnumber_t agno; + + for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCK_GC_TAG) + cancel_delayed_work_sync(&pag->pag_blockgc_work); } /* Enable post-EOF and CoW block auto-reclamation. */ @@ -1014,7 +1029,11 @@ void xfs_blockgc_start( struct xfs_mount *mp) { - xfs_queue_blockgc(mp); + struct xfs_perag *pag; + xfs_agnumber_t agno; + + for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCK_GC_TAG) + xfs_queue_blockgc(pag); } /* @@ -1551,7 +1570,7 @@ __xfs_inode_set_blocks_tag( spin_unlock(&ip->i_mount->m_perag_lock); /* kick off background trimming */ - xfs_queue_blockgc(ip->i_mount); + xfs_queue_blockgc(pag); trace_xfs_perag_set_blockgc(ip->i_mount, pag->pag_agno, -1, _RET_IP_); |