[PATCH 09/25] mm, vmscan: Clear congestion, dirty and need for compaction on a per-node basis
From: Mel Gorman
Date: Mon Jun 08 2015 - 09:57:30 EST
Congested and dirty tracking of a node and whether reclaim should stall
is still based on zone activity. This patch considers whether the kernel
should stall based on node-based reclaim activity.
Signed-off-by: Mel Gorman <mgorman@xxxxxxx>
---
mm/vmscan.c | 54 ++++++++++++++++++++++++------------------------------
1 file changed, 24 insertions(+), 30 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 50aa650ac206..e069decbcfa1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2921,16 +2921,30 @@ static void age_active_anon(struct pglist_data *pgdat,
}
static bool zone_balanced(struct zone *zone, int order,
- unsigned long balance_gap, int classzone_idx)
+ unsigned long balance_gap, int classzone_idx,
+ bool *pgdat_needs_compaction)
{
if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone) +
balance_gap, classzone_idx, 0))
return false;
+ /*
+ * If any eligible zone is balanced then the node is not considered
+ * to be congested or dirty
+ */
+ clear_bit(PGDAT_CONGESTED, &zone->zone_pgdat->flags);
+ clear_bit(PGDAT_DIRTY, &zone->zone_pgdat->flags);
+
if (IS_ENABLED(CONFIG_COMPACTION) && order && compaction_suitable(zone,
order, 0, classzone_idx) == COMPACT_SKIPPED)
return false;
+ /*
+ * If a zone is balanced and compaction can start then there is no
+ * need for kswapd to call compact_pgdat
+ */
+ *pgdat_needs_compaction = false;
+
return true;
}
@@ -2944,6 +2958,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
int classzone_idx)
{
int i;
+ bool dummy;
/* If a direct reclaimer woke kswapd within HZ/10, it's premature */
if (remaining)
@@ -2968,7 +2983,7 @@ static bool prepare_kswapd_sleep(pg_data_t *pgdat, int order, long remaining,
for (i = 0; i <= classzone_idx; i++) {
struct zone *zone = pgdat->node_zones + i;
- if (zone_balanced(zone, order, 0, classzone_idx))
+ if (zone_balanced(zone, order, 0, classzone_idx, &dummy))
return true;
}
@@ -3099,29 +3114,10 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
break;
}
- if (!zone_balanced(zone, order, 0, 0)) {
+ if (!zone_balanced(zone, order, 0, 0,
+ &pgdat_needs_compaction)) {
end_zone = i;
break;
- } else {
- /*
- * If any eligible zone is balanced then the
- * node is not considered congested or dirty.
- */
- clear_bit(PGDAT_CONGESTED, &zone->zone_pgdat->flags);
- clear_bit(PGDAT_DIRTY, &zone->zone_pgdat->flags);
-
- /*
- * If any zone is currently balanced then kswapd will
- * not call compaction as it is expected that the
- * necessary pages are already available.
- */
- if (pgdat_needs_compaction &&
- zone_watermark_ok(zone, order,
- low_wmark_pages(zone),
- *classzone_idx, 0)) {
- pgdat_needs_compaction = false;
- }
-
}
}
@@ -3182,12 +3178,9 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, int order,
*/
for (i = 0; i <= *classzone_idx; i++) {
zone = pgdat->node_zones + i;
-
- if (zone_balanced(zone, sc.order, 0, *classzone_idx)) {
- clear_bit(PGDAT_CONGESTED, &pgdat->flags);
- clear_bit(PGDAT_DIRTY, &pgdat->flags);
- break;
- }
+ if (zone_balanced(zone, sc.order, 0, *classzone_idx,
+ &pgdat_needs_compaction))
+ goto out;
}
/*
@@ -3379,6 +3372,7 @@ static int kswapd(void *p)
void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx)
{
pg_data_t *pgdat;
+ bool dummy;
if (!populated_zone(zone))
return;
@@ -3392,7 +3386,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx)
}
if (!waitqueue_active(&pgdat->kswapd_wait))
return;
- if (zone_balanced(zone, order, 0, 0))
+ if (zone_balanced(zone, order, 0, 0, &dummy))
return;
trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);
--
2.3.5
--
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/