Skip to content

Commit

Permalink
GFS2: Wait properly when flushing the ail list
Browse files Browse the repository at this point in the history
The ail flush code has always relied upon log flushing to prevent
it from spinning needlessly. This fixes it to wait on the last
I/O request submitted (we don't need to wait for all of it)
instead of either spinning with io_schedule or sleeping.

As a result cpu usage of gfs2_logd is much reduced with certain
workloads.

Reported-by: Abhijith Das <adas@redhat.com>
Tested-by: Abhijith Das <adas@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
  • Loading branch information
Steven Whitehouse committed May 21, 2011
1 parent 6d3117b commit 26b06a6
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions fs/gfs2/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,27 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp)
return ret;
}

static void gfs2_ail1_wait(struct gfs2_sbd *sdp)
{
struct gfs2_ail *ai;
struct gfs2_bufdata *bd;
struct buffer_head *bh;

spin_lock(&sdp->sd_ail_lock);
list_for_each_entry_reverse(ai, &sdp->sd_ail1_list, ai_list) {
list_for_each_entry(bd, &ai->ai_ail1_list, bd_ail_st_list) {
bh = bd->bd_bh;
if (!buffer_locked(bh))
continue;
get_bh(bh);
spin_unlock(&sdp->sd_ail_lock);
wait_on_buffer(bh);
brelse(bh);
return;
}
}
spin_unlock(&sdp->sd_ail_lock);
}

/**
* gfs2_ail2_empty_one - Check whether or not a trans in the AIL has been synced
Expand Down Expand Up @@ -878,9 +899,9 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp)
gfs2_log_flush(sdp, NULL);
for (;;) {
gfs2_ail1_start(sdp);
gfs2_ail1_wait(sdp);
if (gfs2_ail1_empty(sdp))
break;
msleep(10);
}
}

Expand Down Expand Up @@ -920,12 +941,14 @@ int gfs2_logd(void *data)

if (gfs2_ail_flush_reqd(sdp)) {
gfs2_ail1_start(sdp);
io_schedule();
gfs2_ail1_wait(sdp);
gfs2_ail1_empty(sdp);
gfs2_log_flush(sdp, NULL);
}

wake_up(&sdp->sd_log_waitq);
if (!gfs2_ail_flush_reqd(sdp))
wake_up(&sdp->sd_log_waitq);

t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;
if (freezing(current))
refrigerator();
Expand Down

0 comments on commit 26b06a6

Please sign in to comment.