aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2008-03-05 21:44:06 -0500
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-17 21:38:01 -0400
commitb589334c7a1fff85d2f009d5db4c34fad48925e9 (patch)
treebc46a7f50dbc5f8c09e86374cea63192ee2f146b /fs/xfs/xfs_log.c
parent3354040897f828644be6ca5783588e9f64a53b8e (diff)
[XFS] Prevent AIL lock contention during transaction completion
When hundreds of processors attempt to commit transactions at the same time, they can contend on the AIL lock when updating the tail LSN held in the in-core log structure. At the moment, the tail LSN is only needed when actually writing out an iclog, so it really does not need to be updated on every single transaction completion - only those that result in switching iclogs and flushing them to disk. The result is that we reduce the number of times we need to grab the AIL lock and the log grant lock by up to two orders of magnitude on large processor count machines. The problem has previously been hidden by AIL lock contention walking the AIL list which was recently solved and uncovered this issue. SGI-PV: 975671 SGI-Modid: xfs-linux-melb:xfs-kern:30504a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 31f2b04f2c97..2e35077ff6b2 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -2813,15 +2813,13 @@ xlog_state_put_ticket(xlog_t *log,
2813 * 2813 *
2814 */ 2814 */
2815STATIC int 2815STATIC int
2816xlog_state_release_iclog(xlog_t *log, 2816xlog_state_release_iclog(
2817 xlog_in_core_t *iclog) 2817 xlog_t *log,
2818 xlog_in_core_t *iclog)
2818{ 2819{
2819 int sync = 0; /* do we sync? */ 2820 int sync = 0; /* do we sync? */
2820 2821
2821 xlog_assign_tail_lsn(log->l_mp);
2822
2823 spin_lock(&log->l_icloglock); 2822 spin_lock(&log->l_icloglock);
2824
2825 if (iclog->ic_state & XLOG_STATE_IOERROR) { 2823 if (iclog->ic_state & XLOG_STATE_IOERROR) {
2826 spin_unlock(&log->l_icloglock); 2824 spin_unlock(&log->l_icloglock);
2827 return XFS_ERROR(EIO); 2825 return XFS_ERROR(EIO);
@@ -2833,13 +2831,14 @@ xlog_state_release_iclog(xlog_t *log,
2833 2831
2834 if (--iclog->ic_refcnt == 0 && 2832 if (--iclog->ic_refcnt == 0 &&
2835 iclog->ic_state == XLOG_STATE_WANT_SYNC) { 2833 iclog->ic_state == XLOG_STATE_WANT_SYNC) {
2834 /* update tail before writing to iclog */
2835 xlog_assign_tail_lsn(log->l_mp);
2836 sync++; 2836 sync++;
2837 iclog->ic_state = XLOG_STATE_SYNCING; 2837 iclog->ic_state = XLOG_STATE_SYNCING;
2838 iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn); 2838 iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn);
2839 xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn); 2839 xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn);
2840 /* cycle incremented when incrementing curr_block */ 2840 /* cycle incremented when incrementing curr_block */
2841 } 2841 }
2842
2843 spin_unlock(&log->l_icloglock); 2842 spin_unlock(&log->l_icloglock);
2844 2843
2845 /* 2844 /*
@@ -2849,11 +2848,9 @@ xlog_state_release_iclog(xlog_t *log,
2849 * this iclog has consistent data, so we ignore IOERROR 2848 * this iclog has consistent data, so we ignore IOERROR
2850 * flags after this point. 2849 * flags after this point.
2851 */ 2850 */
2852 if (sync) { 2851 if (sync)
2853 return xlog_sync(log, iclog); 2852 return xlog_sync(log, iclog);
2854 }
2855 return 0; 2853 return 0;
2856
2857} /* xlog_state_release_iclog */ 2854} /* xlog_state_release_iclog */
2858 2855
2859 2856