aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_trans_ail.c
diff options
context:
space:
mode:
authorJens Axboe <jaxboe@fusionio.com>2011-05-20 14:33:15 -0400
committerJens Axboe <jaxboe@fusionio.com>2011-05-20 14:33:15 -0400
commit698567f3fa790fea37509a54dea855302dd88331 (patch)
tree7a1df976a0eb12cab03e82c18809a30d5482fee4 /fs/xfs/xfs_trans_ail.c
parentd70d0711edd8076ec2ce0ed109106e2df950681b (diff)
parent61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf (diff)
Merge commit 'v2.6.39' into for-2.6.40/core
Since for-2.6.40/core was forked off the 2.6.39 devel tree, we've had churn in the core area that makes it difficult to handle patches for eg cfq or blk-throttle. Instead of requiring that they be based in older versions with bugs that have been fixed later in the rc cycle, merge in 2.6.39 final. Also fixes up conflicts in the below files. Conflicts: drivers/block/paride/pcd.c drivers/cdrom/viocd.c drivers/ide/ide-cd.c Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'fs/xfs/xfs_trans_ail.c')
-rw-r--r--fs/xfs/xfs_trans_ail.c47
1 files changed, 26 insertions, 21 deletions
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index acdb92f14d51..5fc2380092c8 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -346,20 +346,23 @@ xfs_ail_delete(
346 */ 346 */
347STATIC void 347STATIC void
348xfs_ail_worker( 348xfs_ail_worker(
349 struct work_struct *work) 349 struct work_struct *work)
350{ 350{
351 struct xfs_ail *ailp = container_of(to_delayed_work(work), 351 struct xfs_ail *ailp = container_of(to_delayed_work(work),
352 struct xfs_ail, xa_work); 352 struct xfs_ail, xa_work);
353 long tout; 353 xfs_mount_t *mp = ailp->xa_mount;
354 xfs_lsn_t target = ailp->xa_target;
355 xfs_lsn_t lsn;
356 xfs_log_item_t *lip;
357 int flush_log, count, stuck;
358 xfs_mount_t *mp = ailp->xa_mount;
359 struct xfs_ail_cursor *cur = &ailp->xa_cursors; 354 struct xfs_ail_cursor *cur = &ailp->xa_cursors;
360 int push_xfsbufd = 0; 355 xfs_log_item_t *lip;
356 xfs_lsn_t lsn;
357 xfs_lsn_t target;
358 long tout = 10;
359 int flush_log = 0;
360 int stuck = 0;
361 int count = 0;
362 int push_xfsbufd = 0;
361 363
362 spin_lock(&ailp->xa_lock); 364 spin_lock(&ailp->xa_lock);
365 target = ailp->xa_target;
363 xfs_trans_ail_cursor_init(ailp, cur); 366 xfs_trans_ail_cursor_init(ailp, cur);
364 lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn); 367 lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn);
365 if (!lip || XFS_FORCED_SHUTDOWN(mp)) { 368 if (!lip || XFS_FORCED_SHUTDOWN(mp)) {
@@ -368,8 +371,7 @@ xfs_ail_worker(
368 */ 371 */
369 xfs_trans_ail_cursor_done(ailp, cur); 372 xfs_trans_ail_cursor_done(ailp, cur);
370 spin_unlock(&ailp->xa_lock); 373 spin_unlock(&ailp->xa_lock);
371 ailp->xa_last_pushed_lsn = 0; 374 goto out_done;
372 return;
373 } 375 }
374 376
375 XFS_STATS_INC(xs_push_ail); 377 XFS_STATS_INC(xs_push_ail);
@@ -386,8 +388,7 @@ xfs_ail_worker(
386 * lots of contention on the AIL lists. 388 * lots of contention on the AIL lists.
387 */ 389 */
388 lsn = lip->li_lsn; 390 lsn = lip->li_lsn;
389 flush_log = stuck = count = 0; 391 while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) {
390 while ((XFS_LSN_CMP(lip->li_lsn, target) < 0)) {
391 int lock_result; 392 int lock_result;
392 /* 393 /*
393 * If we can lock the item without sleeping, unlock the AIL 394 * If we can lock the item without sleeping, unlock the AIL
@@ -480,21 +481,25 @@ xfs_ail_worker(
480 } 481 }
481 482
482 /* assume we have more work to do in a short while */ 483 /* assume we have more work to do in a short while */
483 tout = 10; 484out_done:
484 if (!count) { 485 if (!count) {
485 /* We're past our target or empty, so idle */ 486 /* We're past our target or empty, so idle */
486 ailp->xa_last_pushed_lsn = 0; 487 ailp->xa_last_pushed_lsn = 0;
487 488
488 /* 489 /*
489 * Check for an updated push target before clearing the 490 * We clear the XFS_AIL_PUSHING_BIT first before checking
490 * XFS_AIL_PUSHING_BIT. If the target changed, we've got more 491 * whether the target has changed. If the target has changed,
491 * work to do. Wait a bit longer before starting that work. 492 * this pushes the requeue race directly onto the result of the
493 * atomic test/set bit, so we are guaranteed that either the
494 * the pusher that changed the target or ourselves will requeue
495 * the work (but not both).
492 */ 496 */
497 clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
493 smp_rmb(); 498 smp_rmb();
494 if (ailp->xa_target == target) { 499 if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
495 clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags); 500 test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
496 return; 501 return;
497 } 502
498 tout = 50; 503 tout = 50;
499 } else if (XFS_LSN_CMP(lsn, target) >= 0) { 504 } else if (XFS_LSN_CMP(lsn, target) >= 0) {
500 /* 505 /*
@@ -553,7 +558,7 @@ xfs_ail_push(
553 * the XFS_AIL_PUSHING_BIT. 558 * the XFS_AIL_PUSHING_BIT.
554 */ 559 */
555 smp_wmb(); 560 smp_wmb();
556 ailp->xa_target = threshold_lsn; 561 xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
557 if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags)) 562 if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
558 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0); 563 queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0);
559} 564}