Re: writeback-highmem

From: Rik van Riel
Date: Fri Jan 21 2005 - 08:47:56 EST


On Thu, 20 Jan 2005, Andrew Morton wrote:

I've held off on this one because the recent throttling fix should have
helped this problem. Has anyone confirmed that this patch still actually
fixes something? If so, what was the scenario?

The throttling fix is not quite enough, a big mkfs can still
completely paralyse the system. Note that the previously
posted patch wasn't quite complete, Larry Woodman spotted an
additional 2 lines that needed changing.

The full patch is:

This patch effectively lowers the dirty limit for mappings which cannot
be cached in highmem, counting the dirty limit as a percentage of lowmem
instead. This should prevent heavy block device writers from pushing
the VM over the edge and triggering OOM kills.

Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>

===== mm/page-writeback.c 1.95 vs edited =====
--- 1.95/mm/page-writeback.c Thu Oct 21 04:39:27 2004
+++ edited/mm/page-writeback.c Fri Jan 21 08:45:24 2005
@@ -133,17 +133,27 @@
* 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;
@@ -157,8 +167,8 @@
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;
@@ -194,7 +204,8 @@
.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;
@@ -210,7 +221,7 @@
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;
@@ -296,7 +307,7 @@
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;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/