aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_ail.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_trans_ail.c')
-rw-r--r--fs/xfs/xfs_trans_ail.c73
1 files changed, 41 insertions, 32 deletions
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index e4cd9180d33a..3a1e7ca54c2d 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -28,8 +28,6 @@
28#include "xfs_trans_priv.h" 28#include "xfs_trans_priv.h"
29#include "xfs_error.h" 29#include "xfs_error.h"
30 30
31struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
32
33#ifdef DEBUG 31#ifdef DEBUG
34/* 32/*
35 * Check that the list is sorted as it should be. 33 * Check that the list is sorted as it should be.
@@ -356,16 +354,10 @@ xfs_ail_delete(
356 xfs_trans_ail_cursor_clear(ailp, lip); 354 xfs_trans_ail_cursor_clear(ailp, lip);
357} 355}
358 356
359/* 357static long
360 * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself 358xfsaild_push(
361 * to run at a later time if there is more work to do to complete the push. 359 struct xfs_ail *ailp)
362 */
363STATIC void
364xfs_ail_worker(
365 struct work_struct *work)
366{ 360{
367 struct xfs_ail *ailp = container_of(to_delayed_work(work),
368 struct xfs_ail, xa_work);
369 xfs_mount_t *mp = ailp->xa_mount; 361 xfs_mount_t *mp = ailp->xa_mount;
370 struct xfs_ail_cursor cur; 362 struct xfs_ail_cursor cur;
371 xfs_log_item_t *lip; 363 xfs_log_item_t *lip;
@@ -505,20 +497,6 @@ out_done:
505 /* We're past our target or empty, so idle */ 497 /* We're past our target or empty, so idle */
506 ailp->xa_last_pushed_lsn = 0; 498 ailp->xa_last_pushed_lsn = 0;
507 499
508 /*
509 * We clear the XFS_AIL_PUSHING_BIT first before checking
510 * whether the target has changed. If the target has changed,
511 * this pushes the requeue race directly onto the result of the
512 * atomic test/set bit, so we are guaranteed that either the
513 * the pusher that changed the target or ourselves will requeue
514 * the work (but not both).
515 */
516 clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
517 smp_rmb();
518 if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
519 test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
520 return;
521
522 tout = 50; 500 tout = 50;
523 } else if (XFS_LSN_CMP(lsn, target) >= 0) { 501 } else if (XFS_LSN_CMP(lsn, target) >= 0) {
524 /* 502 /*
@@ -541,9 +519,30 @@ out_done:
541 tout = 20; 519 tout = 20;
542 } 520 }
543 521
544 /* There is more to do, requeue us. */ 522 return tout;
545 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 523}
546 msecs_to_jiffies(tout)); 524
525static int
526xfsaild(
527 void *data)
528{
529 struct xfs_ail *ailp = data;
530 long tout = 0; /* milliseconds */
531
532 while (!kthread_should_stop()) {
533 if (tout && tout <= 20)
534 __set_current_state(TASK_KILLABLE);
535 else
536 __set_current_state(TASK_INTERRUPTIBLE);
537 schedule_timeout(tout ?
538 msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
539
540 try_to_freeze();
541
542 tout = xfsaild_push(ailp);
543 }
544
545 return 0;
547} 546}
548 547
549/* 548/*
@@ -578,8 +577,9 @@ xfs_ail_push(
578 */ 577 */
579 smp_wmb(); 578 smp_wmb();
580 xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn); 579 xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
581 if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) 580 smp_wmb();
582 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0); 581
582 wake_up_process(ailp->xa_task);
583} 583}
584 584
585/* 585/*
@@ -817,9 +817,18 @@ xfs_trans_ail_init(
817 INIT_LIST_HEAD(&ailp->xa_ail); 817 INIT_LIST_HEAD(&ailp->xa_ail);
818 INIT_LIST_HEAD(&ailp->xa_cursors); 818 INIT_LIST_HEAD(&ailp->xa_cursors);
819 spin_lock_init(&ailp->xa_lock); 819 spin_lock_init(&ailp->xa_lock);
820 INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker); 820
821 ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
822 ailp->xa_mount->m_fsname);
823 if (IS_ERR(ailp->xa_task))
824 goto out_free_ailp;
825
821 mp->m_ail = ailp; 826 mp->m_ail = ailp;
822 return 0; 827 return 0;
828
829out_free_ailp:
830 kmem_free(ailp);
831 return ENOMEM;
823} 832}
824 833
825void 834void
@@ -828,6 +837,6 @@ xfs_trans_ail_destroy(
828{ 837{
829 struct xfs_ail *ailp = mp->m_ail; 838 struct xfs_ail *ailp = mp->m_ail;
830 839
831 cancel_delayed_work_sync(&ailp->xa_work); 840 kthread_stop(ailp->xa_task);
832 kmem_free(ailp); 841 kmem_free(ailp);
833} 842}