Commit 9669f51d authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: consolidate the eofblocks and cowblocks workers

Remove the separate cowblocks work items and knob so that we can control
and run everything from a single blockgc work queue.  Note that the
speculative_prealloc_lifetime sysfs knob retains its historical name
even though the functions move to prefix xfs_blockgc_*.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent ce2d3bbe
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
/* /*
* Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n, * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
* other XFS code uses these values. Times are measured in centisecs (i.e. * other XFS code uses these values. Times are measured in centisecs (i.e.
* 100ths of a second) with the exception of eofb_timer and cowb_timer, which * 100ths of a second) with the exception of blockgc_timer, which is measured
* are measured in seconds. * in seconds.
*/ */
xfs_param_t xfs_params = { xfs_param_t xfs_params = {
/* MIN DFLT MAX */ /* MIN DFLT MAX */
...@@ -28,8 +28,7 @@ xfs_param_t xfs_params = { ...@@ -28,8 +28,7 @@ xfs_param_t xfs_params = {
.rotorstep = { 1, 1, 255 }, .rotorstep = { 1, 1, 255 },
.inherit_nodfrg = { 0, 1, 1 }, .inherit_nodfrg = { 0, 1, 1 },
.fstrm_timer = { 1, 30*100, 3600*100}, .fstrm_timer = { 1, 30*100, 3600*100},
.eofb_timer = { 1, 300, 3600*24}, .blockgc_timer = { 1, 300, 3600*24},
.cowb_timer = { 1, 1800, 3600*24},
}; };
struct xfs_globals xfs_globals = { struct xfs_globals xfs_globals = {
......
...@@ -1328,41 +1328,24 @@ xfs_inode_free_eofblocks( ...@@ -1328,41 +1328,24 @@ xfs_inode_free_eofblocks(
} }
/* /*
* Background scanning to trim post-EOF preallocated space. This is queued * Background scanning to trim preallocated space. This is queued based on the
* based on the 'speculative_prealloc_lifetime' tunable (5m by default). * 'speculative_prealloc_lifetime' tunable (5m by default).
*/ */
void static inline void
xfs_queue_eofblocks( xfs_blockgc_queue(
struct xfs_mount *mp) struct xfs_mount *mp)
{ {
rcu_read_lock(); rcu_read_lock();
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG)) if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
queue_delayed_work(mp->m_eofblocks_workqueue, queue_delayed_work(mp->m_blockgc_workqueue,
&mp->m_eofblocks_work, &mp->m_blockgc_work,
msecs_to_jiffies(xfs_eofb_secs * 1000)); msecs_to_jiffies(xfs_blockgc_secs * 1000));
rcu_read_unlock(); rcu_read_unlock();
} }
void
xfs_eofblocks_worker(
struct work_struct *work)
{
struct xfs_mount *mp = container_of(to_delayed_work(work),
struct xfs_mount, m_eofblocks_work);
if (!sb_start_write_trylock(mp->m_super))
return;
xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, NULL,
XFS_ICI_BLOCKGC_TAG);
sb_end_write(mp->m_super);
xfs_queue_eofblocks(mp);
}
static void static void
xfs_blockgc_set_iflag( xfs_blockgc_set_iflag(
struct xfs_inode *ip, struct xfs_inode *ip,
void (*execute)(struct xfs_mount *mp),
unsigned long iflag) unsigned long iflag)
{ {
struct xfs_mount *mp = ip->i_mount; struct xfs_mount *mp = ip->i_mount;
...@@ -1397,7 +1380,7 @@ xfs_blockgc_set_iflag( ...@@ -1397,7 +1380,7 @@ xfs_blockgc_set_iflag(
spin_unlock(&ip->i_mount->m_perag_lock); spin_unlock(&ip->i_mount->m_perag_lock);
/* kick off background trimming */ /* kick off background trimming */
execute(ip->i_mount); xfs_blockgc_queue(ip->i_mount);
trace_xfs_perag_set_blockgc(ip->i_mount, pag->pag_agno, -1, trace_xfs_perag_set_blockgc(ip->i_mount, pag->pag_agno, -1,
_RET_IP_); _RET_IP_);
...@@ -1412,7 +1395,7 @@ xfs_inode_set_eofblocks_tag( ...@@ -1412,7 +1395,7 @@ xfs_inode_set_eofblocks_tag(
xfs_inode_t *ip) xfs_inode_t *ip)
{ {
trace_xfs_inode_set_eofblocks_tag(ip); trace_xfs_inode_set_eofblocks_tag(ip);
return xfs_blockgc_set_iflag(ip, xfs_queue_eofblocks, XFS_IEOFBLOCKS); return xfs_blockgc_set_iflag(ip, XFS_IEOFBLOCKS);
} }
static void static void
...@@ -1556,45 +1539,12 @@ xfs_inode_free_cowblocks( ...@@ -1556,45 +1539,12 @@ xfs_inode_free_cowblocks(
return ret; return ret;
} }
/*
* Background scanning to trim preallocated CoW space. This is queued
* based on the 'speculative_cow_prealloc_lifetime' tunable (5m by default).
* (We'll just piggyback on the post-EOF prealloc space workqueue.)
*/
void
xfs_queue_cowblocks(
struct xfs_mount *mp)
{
rcu_read_lock();
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
queue_delayed_work(mp->m_eofblocks_workqueue,
&mp->m_cowblocks_work,
msecs_to_jiffies(xfs_cowb_secs * 1000));
rcu_read_unlock();
}
void
xfs_cowblocks_worker(
struct work_struct *work)
{
struct xfs_mount *mp = container_of(to_delayed_work(work),
struct xfs_mount, m_cowblocks_work);
if (!sb_start_write_trylock(mp->m_super))
return;
xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, NULL,
XFS_ICI_BLOCKGC_TAG);
sb_end_write(mp->m_super);
xfs_queue_cowblocks(mp);
}
void void
xfs_inode_set_cowblocks_tag( xfs_inode_set_cowblocks_tag(
xfs_inode_t *ip) xfs_inode_t *ip)
{ {
trace_xfs_inode_set_cowblocks_tag(ip); trace_xfs_inode_set_cowblocks_tag(ip);
return xfs_blockgc_set_iflag(ip, xfs_queue_cowblocks, XFS_ICOWBLOCKS); return xfs_blockgc_set_iflag(ip, XFS_ICOWBLOCKS);
} }
void void
...@@ -1610,8 +1560,7 @@ void ...@@ -1610,8 +1560,7 @@ void
xfs_stop_block_reaping( xfs_stop_block_reaping(
struct xfs_mount *mp) struct xfs_mount *mp)
{ {
cancel_delayed_work_sync(&mp->m_eofblocks_work); cancel_delayed_work_sync(&mp->m_blockgc_work);
cancel_delayed_work_sync(&mp->m_cowblocks_work);
} }
/* Enable post-EOF and CoW block auto-reclamation. */ /* Enable post-EOF and CoW block auto-reclamation. */
...@@ -1619,8 +1568,7 @@ void ...@@ -1619,8 +1568,7 @@ void
xfs_start_block_reaping( xfs_start_block_reaping(
struct xfs_mount *mp) struct xfs_mount *mp)
{ {
xfs_queue_eofblocks(mp); xfs_blockgc_queue(mp);
xfs_queue_cowblocks(mp);
} }
/* Scan all incore inodes for block preallocations that we can remove. */ /* Scan all incore inodes for block preallocations that we can remove. */
...@@ -1644,6 +1592,24 @@ xfs_blockgc_scan( ...@@ -1644,6 +1592,24 @@ xfs_blockgc_scan(
return 0; return 0;
} }
/* Background worker that trims preallocated space. */
void
xfs_blockgc_worker(
struct work_struct *work)
{
struct xfs_mount *mp = container_of(to_delayed_work(work),
struct xfs_mount, m_blockgc_work);
int error;
if (!sb_start_write_trylock(mp->m_super))
return;
error = xfs_blockgc_scan(mp, NULL);
if (error)
xfs_info(mp, "preallocation gc worker failed, err=%d", error);
sb_end_write(mp->m_super);
xfs_blockgc_queue(mp);
}
/* /*
* Try to free space in the filesystem by purging eofblocks and cowblocks. * Try to free space in the filesystem by purging eofblocks and cowblocks.
*/ */
......
...@@ -62,13 +62,11 @@ int xfs_blockgc_free_space(struct xfs_mount *mp, struct xfs_eofblocks *eofb); ...@@ -62,13 +62,11 @@ int xfs_blockgc_free_space(struct xfs_mount *mp, struct xfs_eofblocks *eofb);
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
void xfs_eofblocks_worker(struct work_struct *);
void xfs_queue_eofblocks(struct xfs_mount *);
void xfs_inode_set_cowblocks_tag(struct xfs_inode *ip); void xfs_inode_set_cowblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_cowblocks_tag(struct xfs_inode *ip); void xfs_inode_clear_cowblocks_tag(struct xfs_inode *ip);
void xfs_cowblocks_worker(struct work_struct *);
void xfs_queue_cowblocks(struct xfs_mount *); void xfs_blockgc_worker(struct work_struct *work);
int xfs_inode_walk(struct xfs_mount *mp, int iter_flags, int xfs_inode_walk(struct xfs_mount *mp, int iter_flags,
int (*execute)(struct xfs_inode *ip, void *args), int (*execute)(struct xfs_inode *ip, void *args),
......
...@@ -98,8 +98,7 @@ typedef __u32 xfs_nlink_t; ...@@ -98,8 +98,7 @@ typedef __u32 xfs_nlink_t;
#define xfs_rotorstep xfs_params.rotorstep.val #define xfs_rotorstep xfs_params.rotorstep.val
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
#define xfs_fstrm_centisecs xfs_params.fstrm_timer.val #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val
#define xfs_eofb_secs xfs_params.eofb_timer.val #define xfs_blockgc_secs xfs_params.blockgc_timer.val
#define xfs_cowb_secs xfs_params.cowb_timer.val
#define current_cpu() (raw_smp_processor_id()) #define current_cpu() (raw_smp_processor_id())
#define current_set_flags_nested(sp, f) \ #define current_set_flags_nested(sp, f) \
......
...@@ -93,7 +93,7 @@ typedef struct xfs_mount { ...@@ -93,7 +93,7 @@ typedef struct xfs_mount {
struct workqueue_struct *m_unwritten_workqueue; struct workqueue_struct *m_unwritten_workqueue;
struct workqueue_struct *m_cil_workqueue; struct workqueue_struct *m_cil_workqueue;
struct workqueue_struct *m_reclaim_workqueue; struct workqueue_struct *m_reclaim_workqueue;
struct workqueue_struct *m_eofblocks_workqueue; struct workqueue_struct *m_blockgc_workqueue;
struct workqueue_struct *m_sync_workqueue; struct workqueue_struct *m_sync_workqueue;
int m_bsize; /* fs logical block size */ int m_bsize; /* fs logical block size */
...@@ -177,9 +177,7 @@ typedef struct xfs_mount { ...@@ -177,9 +177,7 @@ typedef struct xfs_mount {
uint64_t m_resblks_avail;/* available reserved blocks */ uint64_t m_resblks_avail;/* available reserved blocks */
uint64_t m_resblks_save; /* reserved blks @ remount,ro */ uint64_t m_resblks_save; /* reserved blks @ remount,ro */
struct delayed_work m_reclaim_work; /* background inode reclaim */ struct delayed_work m_reclaim_work; /* background inode reclaim */
struct delayed_work m_eofblocks_work; /* background eof blocks struct delayed_work m_blockgc_work; /* background prealloc blocks
trimming */
struct delayed_work m_cowblocks_work; /* background cow blocks
trimming */ trimming */
struct xfs_kobj m_kobj; struct xfs_kobj m_kobj;
struct xfs_kobj m_error_kobj; struct xfs_kobj m_error_kobj;
......
...@@ -518,10 +518,10 @@ xfs_init_mount_workqueues( ...@@ -518,10 +518,10 @@ xfs_init_mount_workqueues(
if (!mp->m_reclaim_workqueue) if (!mp->m_reclaim_workqueue)
goto out_destroy_cil; goto out_destroy_cil;
mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", mp->m_blockgc_workqueue = alloc_workqueue("xfs-blockgc/%s",
XFS_WQFLAGS(WQ_FREEZABLE | WQ_MEM_RECLAIM), XFS_WQFLAGS(WQ_FREEZABLE | WQ_MEM_RECLAIM),
0, mp->m_super->s_id); 0, mp->m_super->s_id);
if (!mp->m_eofblocks_workqueue) if (!mp->m_blockgc_workqueue)
goto out_destroy_reclaim; goto out_destroy_reclaim;
mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s", mp->m_sync_workqueue = alloc_workqueue("xfs-sync/%s",
...@@ -532,7 +532,7 @@ xfs_init_mount_workqueues( ...@@ -532,7 +532,7 @@ xfs_init_mount_workqueues(
return 0; return 0;
out_destroy_eofb: out_destroy_eofb:
destroy_workqueue(mp->m_eofblocks_workqueue); destroy_workqueue(mp->m_blockgc_workqueue);
out_destroy_reclaim: out_destroy_reclaim:
destroy_workqueue(mp->m_reclaim_workqueue); destroy_workqueue(mp->m_reclaim_workqueue);
out_destroy_cil: out_destroy_cil:
...@@ -550,7 +550,7 @@ xfs_destroy_mount_workqueues( ...@@ -550,7 +550,7 @@ xfs_destroy_mount_workqueues(
struct xfs_mount *mp) struct xfs_mount *mp)
{ {
destroy_workqueue(mp->m_sync_workqueue); destroy_workqueue(mp->m_sync_workqueue);
destroy_workqueue(mp->m_eofblocks_workqueue); destroy_workqueue(mp->m_blockgc_workqueue);
destroy_workqueue(mp->m_reclaim_workqueue); destroy_workqueue(mp->m_reclaim_workqueue);
destroy_workqueue(mp->m_cil_workqueue); destroy_workqueue(mp->m_cil_workqueue);
destroy_workqueue(mp->m_unwritten_workqueue); destroy_workqueue(mp->m_unwritten_workqueue);
...@@ -1842,8 +1842,7 @@ static int xfs_init_fs_context( ...@@ -1842,8 +1842,7 @@ static int xfs_init_fs_context(
mutex_init(&mp->m_growlock); mutex_init(&mp->m_growlock);
INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker); INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker);
INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); INIT_DELAYED_WORK(&mp->m_blockgc_work, xfs_blockgc_worker);
INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
mp->m_kobj.kobject.kset = xfs_kset; mp->m_kobj.kobject.kset = xfs_kset;
/* /*
* We don't create the finobt per-ag space reservation until after log * We don't create the finobt per-ag space reservation until after log
......
...@@ -194,21 +194,12 @@ static struct ctl_table xfs_table[] = { ...@@ -194,21 +194,12 @@ static struct ctl_table xfs_table[] = {
}, },
{ {
.procname = "speculative_prealloc_lifetime", .procname = "speculative_prealloc_lifetime",
.data = &xfs_params.eofb_timer.val, .data = &xfs_params.blockgc_timer.val,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec_minmax, .proc_handler = proc_dointvec_minmax,
.extra1 = &xfs_params.eofb_timer.min, .extra1 = &xfs_params.blockgc_timer.min,
.extra2 = &xfs_params.eofb_timer.max, .extra2 = &xfs_params.blockgc_timer.max,
},
{
.procname = "speculative_cow_prealloc_lifetime",
.data = &xfs_params.cowb_timer.val,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &xfs_params.cowb_timer.min,
.extra2 = &xfs_params.cowb_timer.max,
}, },
/* please keep this the last entry */ /* please keep this the last entry */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -35,8 +35,7 @@ typedef struct xfs_param { ...@@ -35,8 +35,7 @@ typedef struct xfs_param {
xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */ xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */
xfs_sysctl_val_t eofb_timer; /* Interval between eofb scan wakeups */ xfs_sysctl_val_t blockgc_timer; /* Interval between blockgc scans */
xfs_sysctl_val_t cowb_timer; /* Interval between cowb scan wakeups */
} xfs_param_t; } xfs_param_t;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment