Re: [patch] mm: fix deferred congestion timeout if preferred zone is not allowed

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > diff --git a/mm/vmscan.c b/mm/vmscan.c
> > --- a/mm/vmscan.c
> > +++ b/mm/vmscan.c
> > @@ -2084,7 +2084,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
> >  			struct zone *preferred_zone;
> >  
> >  			first_zones_zonelist(zonelist, gfp_zone(sc->gfp_mask),
> > -							NULL, &preferred_zone);
> > +						&cpuset_current_mems_allowed,
> > +						&preferred_zone);
> >  			wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/10);
> 
> This part looks fine and a worthwhile fix all on its own.

No. Memcg reclaim should be cared cpuset-wall. Please look at shrink_zones().
And, Now I don't think checking only preferred zone is good idea. zone congestion
makes pageout() failure and makes lots lru rotation than necessary.

Following patch care all related zones, but keep sleep 0.1 seconds at maximum.

---
 mm/vmscan.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 55f5c0e..6b453d0 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1868,6 +1868,7 @@ static void shrink_zones(int priority, struct zonelist *zonelist,
 {
 	struct zoneref *z;
 	struct zone *zone;
+	long timeout = HZ/10;
 
 	for_each_zone_zonelist_nodemask(zone, z, zonelist,
 					gfp_zone(sc->gfp_mask), sc->nodemask) {
@@ -1886,6 +1887,32 @@ static void shrink_zones(int priority, struct zonelist *zonelist,
 
 		shrink_zone(priority, zone, sc);
 	}
+
+	/* No heavy pressure. */
+	if (priority >= DEF_PRIORITY - 2)
+		return;
+
+	/* Obviously we didn't issue IO. */
+	if (sc->nr_scanned == 0)
+		return;
+
+	/* Other tasks are freezed. IO congestion is no matter. */
+	if (sc->hibernation_mode)
+		return;
+
+	/* Take a nap, wait for some writeback to complete */
+	for_each_zone_zonelist_nodemask(zone, z, zonelist,
+					gfp_zone(sc->gfp_mask), sc->nodemask) {
+		if (!populated_zone(zone))
+			continue;
+		if (scanning_global_lru(sc) &&
+		    !cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
+			continue;
+
+		timeout = wait_iff_congested(zone, BLK_RW_ASYNC, timeout);
+		if (!timeout)
+			break;
+	}
 }
 
 static bool zone_reclaimable(struct zone *zone)
@@ -1993,16 +2020,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
 			wakeup_flusher_threads(laptop_mode ? 0 : total_scanned);
 			sc->may_writepage = 1;
 		}
-
-		/* Take a nap, wait for some writeback to complete */
-		if (!sc->hibernation_mode && sc->nr_scanned &&
-		    priority < DEF_PRIORITY - 2) {
-			struct zone *preferred_zone;
-
-			first_zones_zonelist(zonelist, gfp_zone(sc->gfp_mask),
-							NULL, &preferred_zone);
-			wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/10);
-		}
 	}
 
 out:
-- 
1.6.5.2



--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/
Don't email: <a href=mailto:"dont@xxxxxxxxx";> email@xxxxxxxxx </a>


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]