Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1572697 > unrolled thread

[PATCH 0/7] mm: vmscan: fix kswapd writeback regression v2

Started byJohannes Weiner <hannes@cmpxchg.org>
First post2017-02-02 20:30 +0100
Last post2017-02-02 23:50 +0100
Articles 7 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/7] mm: vmscan: fix kswapd writeback regression v2 Johannes Weiner <hannes@cmpxchg.org> - 2017-02-02 20:30 +0100
    [PATCH 7/7] mm: vmscan: move dirty pages out of the way until they're flushed fix Johannes Weiner <hannes@cmpxchg.org> - 2017-02-02 20:30 +0100
    [PATCH 4/7] mm: vmscan: remove old flusher wakeup from direct reclaim path Johannes Weiner <hannes@cmpxchg.org> - 2017-02-02 20:30 +0100
    [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed Johannes Weiner <hannes@cmpxchg.org> - 2017-02-02 20:30 +0100
      Re: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed "Hillf Danton" <hillf.zj@alibaba-inc.com> - 2017-02-03 08:50 +0100
        Re: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until  they're flushed Michal Hocko <mhocko@kernel.org> - 2017-02-03 16:20 +0100
    Re: [PATCH 0/7] mm: vmscan: fix kswapd writeback regression v2 Andrew Morton <akpm@linux-foundation.org> - 2017-02-02 23:50 +0100

#1572697 — [PATCH 0/7] mm: vmscan: fix kswapd writeback regression v2

FromJohannes Weiner <hannes@cmpxchg.org>
Date2017-02-02 20:30 +0100
Subject[PATCH 0/7] mm: vmscan: fix kswapd writeback regression v2
Message-ID<t6veV-89s-11@gated-at.bofh.it>
Hi Andrew,

here are some minor updates to the series. It's nothing functional,
just code comments and updates to the changelogs from the mailing list
discussions. Since we don't have a good delta system for changelogs
I'm resending the entire thing as a drop-in replacement for -mm.

These are the changes:

1. mm: vmscan: scan dirty pages even in laptop mode

   Mel tested the entire series, not just one patch. Move his test
   conclusions from 'mm: vmscan: remove old flusher wakeup from direct
   reclaim' into the series header in patch 1. Also, reflect the fact
   that these test results are indeed Mel's, not mine.

2. mm: vmscan: kick flushers when we encounter dirty pages on the LRU

   Mention the trade-off between flush-the-world/flush-the-scanwindow
   type wakeups in the changelog, as per the mailing list discussion.

3. mm: vmscan: move dirty pages out of the way until they're flushed

   Correct the last paragraph in the changelog. We're not activating
   dirty/writeback pages after they have rotated twice; they are being
   activated straight away to get them out of the reclaimer's face.
   This was a vestige from an earlier version of the patch.

4. mm: vmscan: move dirty pages out of the way until they're flushed fix

   Code comment fixlet to explain why we activate dirty/writeback pages.

Thanks!

 include/linux/mm_inline.h        |  7 ++++
 include/linux/mmzone.h           |  2 -
 include/linux/writeback.h        |  2 +-
 include/trace/events/writeback.h |  2 +-
 mm/swap.c                        |  9 +++--
 mm/vmscan.c                      | 77 ++++++++++++++++++--------------------
 6 files changed, 50 insertions(+), 49 deletions(-)

[toc] | [next] | [standalone]


#1572700 — [PATCH 7/7] mm: vmscan: move dirty pages out of the way until they're flushed fix

FromJohannes Weiner <hannes@cmpxchg.org>
Date2017-02-02 20:30 +0100
Subject[PATCH 7/7] mm: vmscan: move dirty pages out of the way until they're flushed fix
Message-ID<t6veW-89s-29@gated-at.bofh.it>
In reply to#1572697
Mention the trade-off between waiting for writeback and potentially
causing hot cache refaults in the code where we make this decisions
and activate writeback pages.

Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
---
 mm/vmscan.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 70103f411247..ae3d982216b5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1056,6 +1056,15 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 		 *    throttling so we could easily OOM just because too many
 		 *    pages are in writeback and there is nothing else to
 		 *    reclaim. Wait for the writeback to complete.
+		 *
+		 * In cases 1) and 2) we activate the pages to get them out of
+		 * the way while we continue scanning for clean pages on the
+		 * inactive list and refilling from the active list. The
+		 * observation here is that waiting for disk writes is more
+		 * expensive than potentially causing reloads down the line.
+		 * Since they're marked for immediate reclaim, they won't put
+		 * memory pressure on the cache working set any longer than it
+		 * takes to write them to disk.
 		 */
 		if (PageWriteback(page)) {
 			/* Case 1 above */
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1572701 — [PATCH 4/7] mm: vmscan: remove old flusher wakeup from direct reclaim path

FromJohannes Weiner <hannes@cmpxchg.org>
Date2017-02-02 20:30 +0100
Subject[PATCH 4/7] mm: vmscan: remove old flusher wakeup from direct reclaim path
Message-ID<t6veW-89s-25@gated-at.bofh.it>
In reply to#1572697
Direct reclaim has been replaced by kswapd reclaim in pretty much all
common memory pressure situations, so this code most likely doesn't
accomplish the described effect anymore.  The previous patch wakes up
flushers for all reclaimers when we encounter dirty pages at the tail end
of the LRU.  Remove the crufty old direct reclaim invocation.

Link: http://lkml.kernel.org/r/20170123181641.23938-4-hannes@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
 mm/vmscan.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 83c92b866afe..ce2ee8331414 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2757,8 +2757,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
 					  struct scan_control *sc)
 {
 	int initial_priority = sc->priority;
-	unsigned long total_scanned = 0;
-	unsigned long writeback_threshold;
 retry:
 	delayacct_freepages_start();
 
@@ -2771,7 +2769,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
 		sc->nr_scanned = 0;
 		shrink_zones(zonelist, sc);
 
-		total_scanned += sc->nr_scanned;
 		if (sc->nr_reclaimed >= sc->nr_to_reclaim)
 			break;
 
@@ -2784,20 +2781,6 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
 		 */
 		if (sc->priority < DEF_PRIORITY - 2)
 			sc->may_writepage = 1;
-
-		/*
-		 * Try to write back as many pages as we just scanned.  This
-		 * tends to cause slow streaming writers to write data to the
-		 * disk smoothly, at the dirtying rate, which is nice.   But
-		 * that's undesirable in laptop mode, where we *want* lumpy
-		 * writeout.  So in laptop mode, write out the whole world.
-		 */
-		writeback_threshold = sc->nr_to_reclaim + sc->nr_to_reclaim / 2;
-		if (total_scanned > writeback_threshold) {
-			wakeup_flusher_threads(laptop_mode ? 0 : total_scanned,
-						WB_REASON_VMSCAN);
-			sc->may_writepage = 1;
-		}
 	} while (--sc->priority >= 0);
 
 	delayacct_freepages_end();
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1572702 — [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed

FromJohannes Weiner <hannes@cmpxchg.org>
Date2017-02-02 20:30 +0100
Subject[PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed
Message-ID<t6veW-89s-31@gated-at.bofh.it>
In reply to#1572697
We noticed a performance regression when moving hadoop workloads from 3.10
kernels to 4.0 and 4.6.  This is accompanied by increased pageout activity
initiated by kswapd as well as frequent bursts of allocation stalls and
direct reclaim scans.  Even lowering the dirty ratios to the equivalent of
less than 1% of memory would not eliminate the issue, suggesting that
dirty pages concentrate where the scanner is looking.

This can be traced back to recent efforts of thrash avoidance.  Where 3.10
would not detect refaulting pages and continuously supply clean cache to
the inactive list, a thrashing workload on 4.0+ will detect and activate
refaulting pages right away, distilling used-once pages on the inactive
list much more effectively.  This is by design, and it makes sense for
clean cache.  But for the most part our workload's cache faults are
refaults and its use-once cache is from streaming writes.  We end up with
most of the inactive list dirty, and we don't go after the active cache as
long as we have use-once pages around.

But waiting for writes to avoid reclaiming clean cache that *might*
refault is a bad trade-off.  Even if the refaults happen, reads are faster
than writes.  Before getting bogged down on writeback, reclaim should
first look at *all* cache in the system, even active cache.

To accomplish this, activate pages that are dirty or under writeback
when they reach the end of the inactive LRU.  The pages are marked for
immediate reclaim, meaning they'll get moved back to the inactive LRU
tail as soon as they're written back and become reclaimable.  But in
the meantime, by reducing the inactive list to only immediately
reclaimable pages, we allow the scanner to deactivate and refill the
inactive list with clean cache from the active list tail to guarantee
forward progress.

Link: http://lkml.kernel.org/r/20170123181641.23938-6-hannes@cmpxchg.org
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Minchan Kim <minchan@kernel.org>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
 include/linux/mm_inline.h | 7 +++++++
 mm/swap.c                 | 9 +++++----
 mm/vmscan.c               | 6 +++---
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 41d376e7116d..e030a68ead7e 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -50,6 +50,13 @@ static __always_inline void add_page_to_lru_list(struct page *page,
 	list_add(&page->lru, &lruvec->lists[lru]);
 }
 
+static __always_inline void add_page_to_lru_list_tail(struct page *page,
+				struct lruvec *lruvec, enum lru_list lru)
+{
+	update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
+	list_add_tail(&page->lru, &lruvec->lists[lru]);
+}
+
 static __always_inline void del_page_from_lru_list(struct page *page,
 				struct lruvec *lruvec, enum lru_list lru)
 {
diff --git a/mm/swap.c b/mm/swap.c
index aabf2e90fe32..c4910f14f957 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -209,9 +209,10 @@ static void pagevec_move_tail_fn(struct page *page, struct lruvec *lruvec,
 {
 	int *pgmoved = arg;
 
-	if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
-		enum lru_list lru = page_lru_base_type(page);
-		list_move_tail(&page->lru, &lruvec->lists[lru]);
+	if (PageLRU(page) && !PageUnevictable(page)) {
+		del_page_from_lru_list(page, lruvec, page_lru(page));
+		ClearPageActive(page);
+		add_page_to_lru_list_tail(page, lruvec, page_lru(page));
 		(*pgmoved)++;
 	}
 }
@@ -235,7 +236,7 @@ static void pagevec_move_tail(struct pagevec *pvec)
  */
 void rotate_reclaimable_page(struct page *page)
 {
-	if (!PageLocked(page) && !PageDirty(page) && !PageActive(page) &&
+	if (!PageLocked(page) && !PageDirty(page) &&
 	    !PageUnevictable(page) && PageLRU(page)) {
 		struct pagevec *pvec;
 		unsigned long flags;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 92e56cadceae..70103f411247 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1063,7 +1063,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 			    PageReclaim(page) &&
 			    test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
 				nr_immediate++;
-				goto keep_locked;
+				goto activate_locked;
 
 			/* Case 2 above */
 			} else if (sane_reclaim(sc) ||
@@ -1081,7 +1081,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 				 */
 				SetPageReclaim(page);
 				nr_writeback++;
-				goto keep_locked;
+				goto activate_locked;
 
 			/* Case 3 above */
 			} else {
@@ -1174,7 +1174,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
 				inc_node_page_state(page, NR_VMSCAN_IMMEDIATE);
 				SetPageReclaim(page);
 
-				goto keep_locked;
+				goto activate_locked;
 			}
 
 			if (references == PAGEREF_RECLAIM_CLEAN)
-- 
2.11.0

[toc] | [prev] | [next] | [standalone]


#1572918 — Re: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed

From"Hillf Danton" <hillf.zj@alibaba-inc.com>
Date2017-02-03 08:50 +0100
SubjectRe: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed
Message-ID<t6GN4-74a-7@gated-at.bofh.it>
In reply to#1572702
On February 03, 2017 3:20 AM Johannes Weiner wrote: 
> @@ -1063,7 +1063,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
>  			    PageReclaim(page) &&
>  			    test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
>  				nr_immediate++;
> -				goto keep_locked;
> +				goto activate_locked;

Out of topic but relevant IMHO, I can't find where it is cleared by grepping:

$ grep -nr PGDAT_WRITEBACK  linux-4.9/mm
linux-4.9/mm/vmscan.c:1019:	test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
linux-4.9/mm/vmscan.c:1777:	set_bit(PGDAT_WRITEBACK, &pgdat->flags);

It was removed in commit 1d82de618dd 
("mm, vmscan: make kswapd reclaim in terms of nodes")

Is it currently maintained somewhere else, Mel and John?

thanks
Hillf

[toc] | [prev] | [next] | [standalone]


#1573141 — Re: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed

FromMichal Hocko <mhocko@kernel.org>
Date2017-02-03 16:20 +0100
SubjectRe: [PATCH 6/7] mm: vmscan: move dirty pages out of the way until they're flushed
Message-ID<t6NOy-3bO-5@gated-at.bofh.it>
In reply to#1572918
On Fri 03-02-17 15:42:55, Hillf Danton wrote:
> 
> On February 03, 2017 3:20 AM Johannes Weiner wrote: 
> > @@ -1063,7 +1063,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
> >  			    PageReclaim(page) &&
> >  			    test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
> >  				nr_immediate++;
> > -				goto keep_locked;
> > +				goto activate_locked;
> 
> Out of topic but relevant IMHO, I can't find where it is cleared by grepping:
> 
> $ grep -nr PGDAT_WRITEBACK  linux-4.9/mm
> linux-4.9/mm/vmscan.c:1019:	test_bit(PGDAT_WRITEBACK, &pgdat->flags)) {
> linux-4.9/mm/vmscan.c:1777:	set_bit(PGDAT_WRITEBACK, &pgdat->flags);

I would just get rid of this flag.

-- 
Michal Hocko
SUSE Labs

[toc] | [prev] | [next] | [standalone]


#1572784

FromAndrew Morton <akpm@linux-foundation.org>
Date2017-02-02 23:50 +0100
Message-ID<t6ymt-1Da-17@gated-at.bofh.it>
In reply to#1572697
On Thu,  2 Feb 2017 14:19:50 -0500 Johannes Weiner <hannes@cmpxchg.org> wrote:

> here are some minor updates to the series. It's nothing functional,
> just code comments and updates to the changelogs from the mailing list
> discussions. Since we don't have a good delta system for changelogs
> I'm resending the entire thing as a drop-in replacement for -mm.

Thanks, I updated the changelogs in place.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web