aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_cil.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2010-05-17 01:52:13 -0400
committerAlex Elder <aelder@sgi.com>2010-05-24 11:38:20 -0400
commitdf806158b0f6eb24247773b4a19b8b59d7217e59 (patch)
treea6fb142258aabf03011aadd14c9cf6ade9033d58 /fs/xfs/xfs_log_cil.c
parent9da1ab181ac1790f86528b86ba5876f037e8dcdc (diff)
xfs: enable background pushing of the CIL
If we let the CIL grow without bound, it will grow large enough to violate recovery constraints (must be at least one complete transaction in the log at all times) or take forever to write out through the log buffers. Hence we need a check during asynchronous transactions as to whether the CIL needs to be pushed. We track the amount of log space the CIL consumes, so it is relatively simple to limit it on a pure size basis. Make the limit the minimum of just under half the log size (recovery constraint) or 8MB of log space (which is an awful lot of metadata). Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r--fs/xfs/xfs_log_cil.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 53abd6b0a333..9b21f80f31ce 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -336,6 +336,7 @@ xfs_log_commit_cil(
336{ 336{
337 struct log *log = mp->m_log; 337 struct log *log = mp->m_log;
338 int log_flags = 0; 338 int log_flags = 0;
339 int push = 0;
339 340
340 if (flags & XFS_TRANS_RELEASE_LOG_RES) 341 if (flags & XFS_TRANS_RELEASE_LOG_RES)
341 log_flags = XFS_LOG_REL_PERM_RESERV; 342 log_flags = XFS_LOG_REL_PERM_RESERV;
@@ -365,8 +366,20 @@ xfs_log_commit_cil(
365 xfs_log_done(mp, tp->t_ticket, NULL, log_flags); 366 xfs_log_done(mp, tp->t_ticket, NULL, log_flags);
366 xfs_trans_unreserve_and_mod_sb(tp); 367 xfs_trans_unreserve_and_mod_sb(tp);
367 368
368 /* background commit is allowed again */ 369 /* check for background commit before unlock */
370 if (log->l_cilp->xc_ctx->space_used > XLOG_CIL_SPACE_LIMIT(log))
371 push = 1;
369 up_read(&log->l_cilp->xc_ctx_lock); 372 up_read(&log->l_cilp->xc_ctx_lock);
373
374 /*
375 * We need to push CIL every so often so we don't cache more than we
376 * can fit in the log. The limit really is that a checkpoint can't be
377 * more than half the log (the current checkpoint is not allowed to
378 * overwrite the previous checkpoint), but commit latency and memory
379 * usage limit this to a smaller size in most cases.
380 */
381 if (push)
382 xlog_cil_push(log, 0);
370 return 0; 383 return 0;
371} 384}
372 385
@@ -429,18 +442,25 @@ xlog_cil_push(
429 if (!cil) 442 if (!cil)
430 return 0; 443 return 0;
431 444
432 /* XXX: don't sleep for background? */
433 new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS); 445 new_ctx = kmem_zalloc(sizeof(*new_ctx), KM_SLEEP|KM_NOFS);
434 new_ctx->ticket = xlog_cil_ticket_alloc(log); 446 new_ctx->ticket = xlog_cil_ticket_alloc(log);
435 447
436 /* lock out transaction commit */ 448 /* lock out transaction commit, but don't block on background push */
437 down_write(&cil->xc_ctx_lock); 449 if (!down_write_trylock(&cil->xc_ctx_lock)) {
450 if (!push_now)
451 goto out_free_ticket;
452 down_write(&cil->xc_ctx_lock);
453 }
438 ctx = cil->xc_ctx; 454 ctx = cil->xc_ctx;
439 455
440 /* check if we've anything to push */ 456 /* check if we've anything to push */
441 if (list_empty(&cil->xc_cil)) 457 if (list_empty(&cil->xc_cil))
442 goto out_skip; 458 goto out_skip;
443 459
460 /* check for spurious background flush */
461 if (!push_now && cil->xc_ctx->space_used < XLOG_CIL_SPACE_LIMIT(log))
462 goto out_skip;
463
444 /* 464 /*
445 * pull all the log vectors off the items in the CIL, and 465 * pull all the log vectors off the items in the CIL, and
446 * remove the items from the CIL. We don't need the CIL lock 466 * remove the items from the CIL. We don't need the CIL lock
@@ -584,6 +604,7 @@ restart:
584 604
585out_skip: 605out_skip:
586 up_write(&cil->xc_ctx_lock); 606 up_write(&cil->xc_ctx_lock);
607out_free_ticket:
587 xfs_log_ticket_put(new_ctx->ticket); 608 xfs_log_ticket_put(new_ctx->ticket);
588 kmem_free(new_ctx); 609 kmem_free(new_ctx);
589 return 0; 610 return 0;