diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-03-11 11:52:25 +0000 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-03-11 11:52:25 +0000 |
commit | d6a079e82efd5fcbb1c7295f22e123c2cc748018 (patch) | |
tree | f95f3369dfb560bfc5d282577ca1edec0487e1d7 /fs/gfs2/glops.c | |
parent | e4a7b7b0c98efcdcc4c1f6eb10925dec1fbc4016 (diff) |
GFS2: introduce AIL lock
The log lock is currently used to protect the AIL lists and
the movements of buffers into and out of them. The lists
are self contained and no log specific items outside the
lists are accessed when starting or emptying the AIL lists.
Hence the operation of the AIL does not require the protection
of the log lock so split them out into a new AIL specific lock
to reduce the amount of traffic on the log lock. This will
also reduce the amount of serialisation that occurs when
the gfs2_logd pushes on the AIL to move it forward.
This reduces the impact of log pushing on sequential write
throughput.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index ac5fac948f87..3754e3cbf02b 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -56,20 +56,26 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) BUG_ON(current->journal_info); current->journal_info = &tr; - gfs2_log_lock(sdp); + spin_lock(&sdp->sd_ail_lock); while (!list_empty(head)) { bd = list_entry(head->next, struct gfs2_bufdata, bd_ail_gl_list); bh = bd->bd_bh; gfs2_remove_from_ail(bd); + spin_unlock(&sdp->sd_ail_lock); + bd->bd_bh = NULL; bh->b_private = NULL; bd->bd_blkno = bh->b_blocknr; + gfs2_log_lock(sdp); gfs2_assert_withdraw(sdp, !buffer_busy(bh)); gfs2_trans_add_revoke(sdp, bd); + gfs2_log_unlock(sdp); + + spin_lock(&sdp->sd_ail_lock); } gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); - gfs2_log_unlock(sdp); + spin_unlock(&sdp->sd_ail_lock); gfs2_trans_end(sdp); gfs2_log_flush(sdp, NULL); |