On Thu, 26 Jan 2012 14:59:58 -0500 Rik van Riel <riel@xxxxxxxxxx> wrote: > With CONFIG_COMPACTION enabled, kswapd does not try to free > contiguous free pages, even when it is woken for a higher order > request. > > This could be bad for eg. jumbo frame network allocations, which > are done from interrupt context and cannot compact memory themselves. > Higher than before allocation failure rates in the network receive > path have been observed in kernels with compaction enabled. > > Teach kswapd to defragment the memory zones in a node, but only > if required and compaction is not deferred in a zone. > > ... > > --- a/mm/vmscan.c > +++ b/mm/vmscan.c > @@ -2673,6 +2673,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order, > int priority; > int i; > int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ > + int zones_need_compaction = 1; > unsigned long total_scanned; > struct reclaim_state *reclaim_state = current->reclaim_state; > unsigned long nr_soft_reclaimed; > @@ -2937,9 +2938,17 @@ out: > goto loop_again; > } > > + /* Check if the memory needs to be defragmented. */ > + if (zone_watermark_ok(zone, order, > + low_wmark_pages(zone), *classzone_idx, 0)) > + zones_need_compaction = 0; > + > /* If balanced, clear the congested flag */ > zone_clear_flag(zone, ZONE_CONGESTED); > } > + > + if (zones_need_compaction) > + compact_pgdat(pgdat, order); > } Nicer: From: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Subject: vmscan-kswapd-carefully-call-compaction-fix reduce scope of zones_need_compaction Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Hillf Danton <dhillf@xxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx> Cc: Mel Gorman <mel@xxxxxxxxx> Cc: Minchan Kim <minchan.kim@xxxxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/vmscan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) --- a/mm/vmscan.c~vmscan-kswapd-carefully-call-compaction-fix +++ a/mm/vmscan.c @@ -2672,7 +2672,6 @@ static unsigned long balance_pgdat(pg_da int priority; int i; int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ - int zones_need_compaction = 1; unsigned long total_scanned; struct reclaim_state *reclaim_state = current->reclaim_state; unsigned long nr_soft_reclaimed; @@ -2920,6 +2919,8 @@ out: * and it is potentially going to sleep here. */ if (order) { + int zones_need_compaction = 1; + for (i = 0; i <= end_zone; i++) { struct zone *zone = pgdat->node_zones + i; _ (could have given it type "bool", but that seems unnecessary when it has "needs" in the name) -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>