diff options
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r-- | mm/page-writeback.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index a3278f005230..50f08241f981 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -128,7 +128,6 @@ unsigned long global_dirty_limit; | |||
128 | * | 128 | * |
129 | */ | 129 | */ |
130 | static struct prop_descriptor vm_completions; | 130 | static struct prop_descriptor vm_completions; |
131 | static struct prop_descriptor vm_dirties; | ||
132 | 131 | ||
133 | /* | 132 | /* |
134 | * couple the period to the dirty_ratio: | 133 | * couple the period to the dirty_ratio: |
@@ -154,7 +153,6 @@ static void update_completion_period(void) | |||
154 | { | 153 | { |
155 | int shift = calc_period_shift(); | 154 | int shift = calc_period_shift(); |
156 | prop_change_shift(&vm_completions, shift); | 155 | prop_change_shift(&vm_completions, shift); |
157 | prop_change_shift(&vm_dirties, shift); | ||
158 | 156 | ||
159 | writeback_set_ratelimit(); | 157 | writeback_set_ratelimit(); |
160 | } | 158 | } |
@@ -235,11 +233,6 @@ void bdi_writeout_inc(struct backing_dev_info *bdi) | |||
235 | } | 233 | } |
236 | EXPORT_SYMBOL_GPL(bdi_writeout_inc); | 234 | EXPORT_SYMBOL_GPL(bdi_writeout_inc); |
237 | 235 | ||
238 | void task_dirty_inc(struct task_struct *tsk) | ||
239 | { | ||
240 | prop_inc_single(&vm_dirties, &tsk->dirties); | ||
241 | } | ||
242 | |||
243 | /* | 236 | /* |
244 | * Obtain an accurate fraction of the BDI's portion. | 237 | * Obtain an accurate fraction of the BDI's portion. |
245 | */ | 238 | */ |
@@ -418,8 +411,13 @@ void global_dirty_limits(unsigned long *pbackground, unsigned long *pdirty) | |||
418 | * | 411 | * |
419 | * Returns @bdi's dirty limit in pages. The term "dirty" in the context of | 412 | * Returns @bdi's dirty limit in pages. The term "dirty" in the context of |
420 | * dirty balancing includes all PG_dirty, PG_writeback and NFS unstable pages. | 413 | * dirty balancing includes all PG_dirty, PG_writeback and NFS unstable pages. |
421 | * And the "limit" in the name is not seriously taken as hard limit in | 414 | * |
422 | * balance_dirty_pages(). | 415 | * Note that balance_dirty_pages() will only seriously take it as a hard limit |
416 | * when sleeping max_pause per page is not enough to keep the dirty pages under | ||
417 | * control. For example, when the device is completely stalled due to some error | ||
418 | * conditions, or when there are 1000 dd tasks writing to a slow 10MB/s USB key. | ||
419 | * In the other normal situations, it acts more gently by throttling the tasks | ||
420 | * more (rather than completely block them) when the bdi dirty pages go high. | ||
423 | * | 421 | * |
424 | * It allocates high/low dirty limits to fast/slow devices, in order to prevent | 422 | * It allocates high/low dirty limits to fast/slow devices, in order to prevent |
425 | * - starving fast devices | 423 | * - starving fast devices |
@@ -601,6 +599,13 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, | |||
601 | */ | 599 | */ |
602 | if (unlikely(bdi_thresh > thresh)) | 600 | if (unlikely(bdi_thresh > thresh)) |
603 | bdi_thresh = thresh; | 601 | bdi_thresh = thresh; |
602 | /* | ||
603 | * It's very possible that bdi_thresh is close to 0 not because the | ||
604 | * device is slow, but that it has remained inactive for long time. | ||
605 | * Honour such devices a reasonable good (hopefully IO efficient) | ||
606 | * threshold, so that the occasional writes won't be blocked and active | ||
607 | * writes can rampup the threshold quickly. | ||
608 | */ | ||
604 | bdi_thresh = max(bdi_thresh, (limit - dirty) / 8); | 609 | bdi_thresh = max(bdi_thresh, (limit - dirty) / 8); |
605 | /* | 610 | /* |
606 | * scale global setpoint to bdi's: | 611 | * scale global setpoint to bdi's: |
@@ -984,8 +989,7 @@ static unsigned long bdi_max_pause(struct backing_dev_info *bdi, | |||
984 | * | 989 | * |
985 | * 8 serves as the safety ratio. | 990 | * 8 serves as the safety ratio. |
986 | */ | 991 | */ |
987 | if (bdi_dirty) | 992 | t = min(t, bdi_dirty * HZ / (8 * bw + 1)); |
988 | t = min(t, bdi_dirty * HZ / (8 * bw + 1)); | ||
989 | 993 | ||
990 | /* | 994 | /* |
991 | * The pause time will be settled within range (max_pause/4, max_pause). | 995 | * The pause time will be settled within range (max_pause/4, max_pause). |
@@ -1133,17 +1137,30 @@ pause: | |||
1133 | pages_dirtied, | 1137 | pages_dirtied, |
1134 | pause, | 1138 | pause, |
1135 | start_time); | 1139 | start_time); |
1136 | __set_current_state(TASK_UNINTERRUPTIBLE); | 1140 | __set_current_state(TASK_KILLABLE); |
1137 | io_schedule_timeout(pause); | 1141 | io_schedule_timeout(pause); |
1138 | 1142 | ||
1139 | dirty_thresh = hard_dirty_limit(dirty_thresh); | ||
1140 | /* | 1143 | /* |
1141 | * max-pause area. If dirty exceeded but still within this | 1144 | * This is typically equal to (nr_dirty < dirty_thresh) and can |
1142 | * area, no need to sleep for more than 200ms: (a) 8 pages per | 1145 | * also keep "1000+ dd on a slow USB stick" under control. |
1143 | * 200ms is typically more than enough to curb heavy dirtiers; | ||
1144 | * (b) the pause time limit makes the dirtiers more responsive. | ||
1145 | */ | 1146 | */ |
1146 | if (nr_dirty < dirty_thresh) | 1147 | if (task_ratelimit) |
1148 | break; | ||
1149 | |||
1150 | /* | ||
1151 | * In the case of an unresponding NFS server and the NFS dirty | ||
1152 | * pages exceeds dirty_thresh, give the other good bdi's a pipe | ||
1153 | * to go through, so that tasks on them still remain responsive. | ||
1154 | * | ||
1155 | * In theory 1 page is enough to keep the comsumer-producer | ||
1156 | * pipe going: the flusher cleans 1 page => the task dirties 1 | ||
1157 | * more page. However bdi_dirty has accounting errors. So use | ||
1158 | * the larger and more IO friendly bdi_stat_error. | ||
1159 | */ | ||
1160 | if (bdi_dirty <= bdi_stat_error(bdi)) | ||
1161 | break; | ||
1162 | |||
1163 | if (fatal_signal_pending(current)) | ||
1147 | break; | 1164 | break; |
1148 | } | 1165 | } |
1149 | 1166 | ||
@@ -1395,7 +1412,6 @@ void __init page_writeback_init(void) | |||
1395 | 1412 | ||
1396 | shift = calc_period_shift(); | 1413 | shift = calc_period_shift(); |
1397 | prop_descriptor_init(&vm_completions, shift); | 1414 | prop_descriptor_init(&vm_completions, shift); |
1398 | prop_descriptor_init(&vm_dirties, shift); | ||
1399 | } | 1415 | } |
1400 | 1416 | ||
1401 | /** | 1417 | /** |
@@ -1724,7 +1740,6 @@ void account_page_dirtied(struct page *page, struct address_space *mapping) | |||
1724 | __inc_zone_page_state(page, NR_DIRTIED); | 1740 | __inc_zone_page_state(page, NR_DIRTIED); |
1725 | __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); | 1741 | __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); |
1726 | __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED); | 1742 | __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED); |
1727 | task_dirty_inc(current); | ||
1728 | task_io_account_write(PAGE_CACHE_SIZE); | 1743 | task_io_account_write(PAGE_CACHE_SIZE); |
1729 | } | 1744 | } |
1730 | } | 1745 | } |