* clamping level.
*/
static void
-get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty)
+get_dirty_limits(struct writeback_state *wbs, long *pbackground, long *pdirty,
+ struct address_space *mapping)
{
int background_ratio; /* Percentages */
int dirty_ratio;
int unmapped_ratio;
long background;
long dirty;
+ unsigned long available_memory = total_pages;
struct task_struct *tsk;
get_writeback_state(wbs);
+#ifdef CONFIG_HIGHMEM
+ /*
+ * If this mapping can only allocate from low memory,
+ * we exclude high memory from our count.
+ */
+ if (mapping && !(mapping_gfp_mask(mapping) & __GFP_HIGHMEM))
+ available_memory -= totalhigh_pages;
+#endif
+
+
unmapped_ratio = 100 - (wbs->nr_mapped * 100) / total_pages;
dirty_ratio = vm_dirty_ratio;
if (background_ratio >= dirty_ratio)
background_ratio = dirty_ratio / 2;
- background = (background_ratio * total_pages) / 100;
- dirty = (dirty_ratio * total_pages) / 100;
+ background = (background_ratio * available_memory) / 100;
+ dirty = (dirty_ratio * available_memory) / 100;
tsk = current;
if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) {
background += background / 4;
.nr_to_write = write_chunk,
};
- get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+ get_dirty_limits(&wbs, &background_thresh,
+ &dirty_thresh, mapping);
nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
break;
if (nr_reclaimable) {
writeback_inodes(&wbc);
get_dirty_limits(&wbs, &background_thresh,
- &dirty_thresh);
+ &dirty_thresh, mapping);
nr_reclaimable = wbs.nr_dirty + wbs.nr_unstable;
if (nr_reclaimable + wbs.nr_writeback <= dirty_thresh)
break;
long background_thresh;
long dirty_thresh;
- get_dirty_limits(&wbs, &background_thresh, &dirty_thresh);
+ get_dirty_limits(&wbs, &background_thresh, &dirty_thresh, NULL);
if (wbs.nr_dirty + wbs.nr_unstable < background_thresh
&& min_pages <= 0)
break;
dirty_background_ratio /= 100;
vm_dirty_ratio *= correction;
vm_dirty_ratio /= 100;
+
+ if (dirty_background_ratio <= 0)
+ dirty_background_ratio = 1;
+ if (vm_dirty_ratio <= 0)
+ vm_dirty_ratio = 1;
}
mod_timer(&wb_timer, jiffies + (dirty_writeback_centisecs * HZ) / 100);
set_ratelimit();
if (!TestSetPageDirty(page)) {
struct address_space *mapping = page_mapping(page);
+ struct address_space *mapping2;
if (mapping) {
spin_lock_irq(&mapping->tree_lock);
- mapping = page_mapping(page);
- if (page_mapping(page)) { /* Race with truncate? */
- BUG_ON(page_mapping(page) != mapping);
+ mapping2 = page_mapping(page);
+ if (mapping2) { /* Race with truncate? */
+ BUG_ON(mapping2 != mapping);
if (!mapping->backing_dev_info->memory_backed)
inc_page_state(nr_dirty);
radix_tree_tag_set(&mapping->page_tree,