[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20160122152049.GA24420@node.shutemov.name>
Date: Fri, 22 Jan 2016 17:20:50 +0200
From: "Kirill A. Shutemov" <kirill@...temov.name>
To: Andrea Arcangeli <aarcange@...hat.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Hugh Dickins <hughd@...gle.com>,
Dave Hansen <dave.hansen@...el.com>,
Mel Gorman <mgorman@...e.de>, Rik van Riel <riel@...hat.com>,
Vlastimil Babka <vbabka@...e.cz>,
Christoph Lameter <cl@...two.org>,
Naoya Horiguchi <n-horiguchi@...jp.nec.com>,
Steve Capper <steve.capper@...aro.org>,
"Aneesh Kumar K.V" <aneesh.kumar@...ux.vnet.ibm.com>,
Johannes Weiner <hannes@...xchg.org>,
Michal Hocko <mhocko@...e.cz>,
Jerome Marchand <jmarchan@...hat.com>,
Sasha Levin <sasha.levin@...cle.com>,
linux-kernel@...r.kernel.org, linux-mm@...ck.org
Subject: Re: [PATCH 2/3] thp: change deferred_split_count() to return number
of THP in queue
On Fri, Jan 22, 2016 at 03:31:27PM +0100, Andrea Arcangeli wrote:
> On Thu, Jan 21, 2016 at 03:09:22PM +0300, Kirill A. Shutemov wrote:
> > @@ -3511,7 +3506,7 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
> > list_splice_tail(&list, &pgdata->split_queue);
> > spin_unlock_irqrestore(&pgdata->split_queue_lock, flags);
> >
> > - return split * HPAGE_PMD_NR / 2;
> > + return split;
> > }
>
> Looking further at how the caller processes this "split" retval, if
> the list has been fully shrunk by the page freeing, between the
> split_count and split_scan, the caller seems to ignore a 0 value
> returned above and it'll keep calling even if sc->nr_to_scan isn't
> decreasing. The caller won't even check sc->nr_to_scan to notice that
> it isn't decreasing anymore, it's write-only as far as the caller is
> concerned.
>
> It's also weird we can't return the number of freed pages and break
> the loop with just one invocation of the split_scan, but that's a
> slight inefficiency in the caller interface. The caller also seems to
> forget to set total_scan to 0 if SHRINK_STOP was returned but perhaps
> that's on purpose, however for our purpose it'd be better off if it
> did.
>
> The split_queue.next is going to be hot in the CPU cache anyway, so
> unless we change the caller, it should be worth it to add a list_empty
> check and return SHRINK_STOP if it was empty. Doing it at the start or
> end doesn't make much difference, at the end lockless it'll deal with
> the split failures too if any.
>
> return split ? : list_empty(&pgdat->split_queue) ? SPLIT_STOP : 0;
Ughh. Shrinker interface is confusing.
>From ed85b527b2ea5c0b8ed93d9d212f9f0d25cae3ab Mon Sep 17 00:00:00 2001
From: "Kirill A. Shutemov" <kirill.shutemov@...ux.intel.com>
Date: Fri, 22 Jan 2016 18:10:59 +0300
Subject: [PATCH] thp: deferred_split_scan(): stop shrinker if the queue is
empty
If pages on queue were freed under us, deferred_split_scan() would
return zero. It makes caller keep calling deferred_split_scan() without
any result.
Let's return SHRINK_STOP in this situation.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@...ux.intel.com>
Suggested-by: Andrea Arcangeli <aarcange@...hat.com>
---
mm/huge_memory.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 298dbc001b07..2ea5e26ce069 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3508,6 +3508,12 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
list_splice_tail(&list, &pgdata->split_queue);
spin_unlock_irqrestore(&pgdata->split_queue_lock, flags);
+ /*
+ * Stop shrinker, if we didn't split any page, but the queue is empty.
+ * This can happen if pages were freed under us.
+ */
+ if (!split && list_empty(&pgdata->split_queue))
+ return SHRINK_STOP;
return split;
}
--
Kirill A. Shutemov
Powered by blists - more mailing lists