Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 274360
b: refs/heads/master
c: c8462cc
h: refs/heads/master
v: v3
  • Loading branch information
Wu Fengguang committed Oct 3, 2011
1 parent fcd09d5 commit 5c0a330
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 143dfe8611a63030ce0c79419dc362f7838be557
refs/heads/master: c8462cc9de9e92264ec647903772f6036a99b286
44 changes: 42 additions & 2 deletions trunk/mm/page-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,43 @@ static unsigned long dirty_poll_interval(unsigned long dirty,
return 1;
}

static unsigned long bdi_max_pause(struct backing_dev_info *bdi,
unsigned long bdi_dirty)
{
unsigned long bw = bdi->avg_write_bandwidth;
unsigned long hi = ilog2(bw);
unsigned long lo = ilog2(bdi->dirty_ratelimit);
unsigned long t;

/* target for 20ms max pause on 1-dd case */
t = HZ / 50;

/*
* Scale up pause time for concurrent dirtiers in order to reduce CPU
* overheads.
*
* (N * 20ms) on 2^N concurrent tasks.
*/
if (hi > lo)
t += (hi - lo) * (20 * HZ) / 1024;

/*
* Limit pause time for small memory systems. If sleeping for too long
* time, a small pool of dirty/writeback pages may go empty and disk go
* idle.
*
* 8 serves as the safety ratio.
*/
if (bdi_dirty)
t = min(t, bdi_dirty * HZ / (8 * bw + 1));

/*
* The pause time will be settled within range (max_pause/4, max_pause).
* Apply a minimal value of 4 to get a non-zero max_pause/4.
*/
return clamp_val(t, 4, MAX_PAUSE);
}

/*
* balance_dirty_pages() must be called by processes which are generating dirty
* data. It looks at the number of dirty pages in the machine and will force
Expand All @@ -958,6 +995,7 @@ static void balance_dirty_pages(struct address_space *mapping,
unsigned long dirty_thresh;
unsigned long bdi_thresh;
long pause = 0;
long max_pause;
bool dirty_exceeded = false;
unsigned long task_ratelimit;
unsigned long dirty_ratelimit;
Expand Down Expand Up @@ -1035,18 +1073,20 @@ static void balance_dirty_pages(struct address_space *mapping,
nr_dirty, bdi_thresh, bdi_dirty,
start_time);

max_pause = bdi_max_pause(bdi, bdi_dirty);

dirty_ratelimit = bdi->dirty_ratelimit;
pos_ratio = bdi_position_ratio(bdi, dirty_thresh,
background_thresh, nr_dirty,
bdi_thresh, bdi_dirty);
if (unlikely(pos_ratio == 0)) {
pause = MAX_PAUSE;
pause = max_pause;
goto pause;
}
task_ratelimit = (u64)dirty_ratelimit *
pos_ratio >> RATELIMIT_CALC_SHIFT;
pause = (HZ * pages_dirtied) / (task_ratelimit | 1);
pause = min_t(long, pause, MAX_PAUSE);
pause = min(pause, max_pause);

pause:
__set_current_state(TASK_UNINTERRUPTIBLE);
Expand Down

0 comments on commit 5c0a330

Please sign in to comment.