Skip to content

Commit

Permalink
xfs: convert the xfsaild threads to a workqueue
Browse files Browse the repository at this point in the history
Similar to the xfssyncd, the per-filesystem xfsaild threads can be
converted to a global workqueue and run periodically by delayed
works. This makes sense for the AIL pushing because it uses
variable timeouts depending on the work that needs to be done.

By removing the xfsaild, we simplify the AIL pushing code and
remove the need to spread the code to implement the threading
and pushing across multiple files.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alex Elder <aelder@sgi.com>
  • Loading branch information
Dave Chinner authored and Dave Chinner committed Apr 8, 2011
1 parent a7b339f commit 0bf6a5b
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 151 deletions.
127 changes: 43 additions & 84 deletions fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -816,75 +816,6 @@ xfs_setup_devices(
return 0;
}

/*
* XFS AIL push thread support
*/
void
xfsaild_wakeup(
struct xfs_ail *ailp,
xfs_lsn_t threshold_lsn)
{
/* only ever move the target forwards */
if (XFS_LSN_CMP(threshold_lsn, ailp->xa_target) > 0) {
ailp->xa_target = threshold_lsn;
wake_up_process(ailp->xa_task);
}
}

STATIC int
xfsaild(
void *data)
{
struct xfs_ail *ailp = data;
xfs_lsn_t last_pushed_lsn = 0;
long tout = 0; /* milliseconds */

while (!kthread_should_stop()) {
/*
* for short sleeps indicating congestion, don't allow us to
* get woken early. Otherwise all we do is bang on the AIL lock
* without making progress.
*/
if (tout && tout <= 20)
__set_current_state(TASK_KILLABLE);
else
__set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(tout ?
msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);

/* swsusp */
try_to_freeze();

ASSERT(ailp->xa_mount->m_log);
if (XFS_FORCED_SHUTDOWN(ailp->xa_mount))
continue;

tout = xfsaild_push(ailp, &last_pushed_lsn);
}

return 0;
} /* xfsaild */

int
xfsaild_start(
struct xfs_ail *ailp)
{
ailp->xa_target = 0;
ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
ailp->xa_mount->m_fsname);
if (IS_ERR(ailp->xa_task))
return -PTR_ERR(ailp->xa_task);
return 0;
}

void
xfsaild_stop(
struct xfs_ail *ailp)
{
kthread_stop(ailp->xa_task);
}


/* Catch misguided souls that try to use this interface on XFS */
STATIC struct inode *
xfs_fs_alloc_inode(
Expand Down Expand Up @@ -1785,6 +1716,38 @@ xfs_destroy_zones(void)

}

STATIC int __init
xfs_init_workqueues(void)
{
/*
* max_active is set to 8 to give enough concurency to allow
* multiple work operations on each CPU to run. This allows multiple
* filesystems to be running sync work concurrently, and scales with
* the number of CPUs in the system.
*/
xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
if (!xfs_syncd_wq)
goto out;

xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8);
if (!xfs_ail_wq)
goto out_destroy_syncd;

return 0;

out_destroy_syncd:
destroy_workqueue(xfs_syncd_wq);
out:
return -ENOMEM;
}

STATIC void __exit
xfs_destroy_workqueues(void)
{
destroy_workqueue(xfs_ail_wq);
destroy_workqueue(xfs_syncd_wq);
}

STATIC int __init
init_xfs_fs(void)
{
Expand All @@ -1800,10 +1763,14 @@ init_xfs_fs(void)
if (error)
goto out;

error = xfs_mru_cache_init();
error = xfs_init_workqueues();
if (error)
goto out_destroy_zones;

error = xfs_mru_cache_init();
if (error)
goto out_destroy_wq;

error = xfs_filestream_init();
if (error)
goto out_mru_cache_uninit;
Expand All @@ -1820,27 +1787,17 @@ init_xfs_fs(void)
if (error)
goto out_cleanup_procfs;

/*
* max_active is set to 8 to give enough concurency to allow
* multiple work operations on each CPU to run. This allows multiple
* filesystems to be running sync work concurrently, and scales with
* the number of CPUs in the system.
*/
xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
if (!xfs_syncd_wq) {
error = -ENOMEM;
error = xfs_init_workqueues();
if (error)
goto out_sysctl_unregister;
}

vfs_initquota();

error = register_filesystem(&xfs_fs_type);
if (error)
goto out_destroy_xfs_syncd;
goto out_sysctl_unregister;
return 0;

out_destroy_xfs_syncd:
destroy_workqueue(xfs_syncd_wq);
out_sysctl_unregister:
xfs_sysctl_unregister();
out_cleanup_procfs:
Expand All @@ -1851,6 +1808,8 @@ init_xfs_fs(void)
xfs_filestream_uninit();
out_mru_cache_uninit:
xfs_mru_cache_uninit();
out_destroy_wq:
xfs_destroy_workqueues();
out_destroy_zones:
xfs_destroy_zones();
out:
Expand All @@ -1862,12 +1821,12 @@ exit_xfs_fs(void)
{
vfs_exitquota();
unregister_filesystem(&xfs_fs_type);
destroy_workqueue(xfs_syncd_wq);
xfs_sysctl_unregister();
xfs_cleanup_procfs();
xfs_buf_terminate();
xfs_filestream_uninit();
xfs_mru_cache_uninit();
xfs_destroy_workqueues();
xfs_destroy_zones();
}

Expand Down
Loading

0 comments on commit 0bf6a5b

Please sign in to comment.