linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
	Rik van Riel <riel@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Mel Gorman <mgorman@suse.de>,
	Johannes Weiner <hannes@cmpxchg.org>,
	Minchan Kim <minchan@kernel.org>,
	Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>,
	Zhang Yanfei <zhangyanfei@cn.fujitsu.com>,
	"Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>,
	Tang Chen <tangchen@cn.fujitsu.com>,
	Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Wen Congyang <wency@cn.fujitsu.com>,
	Marek Szyprowski <m.szyprowski@samsung.com>,
	Michal Nazarewicz <mina86@mina86.com>,
	Laura Abbott <lauraa@codeaurora.org>,
	Heesub Shin <heesub.shin@samsung.com>,
	"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>,
	Ritesh Harjani <ritesh.list@gmail.com>,
	t.stanislaws@samsung.com, Gioh Kim <gioh.kim@lge.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	Joonsoo Kim <iamjoonsoo.kim@lge.com>
Subject: [PATCH 05/10] mm/page_alloc: optimize and unify pageblock migratetype check in free path
Date: Fri,  4 Jul 2014 16:57:50 +0900	[thread overview]
Message-ID: <1404460675-24456-6-git-send-email-iamjoonsoo.kim@lge.com> (raw)
In-Reply-To: <1404460675-24456-1-git-send-email-iamjoonsoo.kim@lge.com>

Currently, when we free the page from pcp list to buddy, we check
pageblock of the page in order to isolate the page on isolated
pageblock. Although this could rarely happen and to check migratetype of
pageblock is somewhat expensive, we check it on free fast path. I think
that this is undesirable. To prevent this situation, I introduce new
variable, nr_isolate_pageblock on struct zone and use it to determine
if we should check pageblock migratetype. Isolation on pageblock rarely
happens so we can mostly avoid this pageblock migratetype check.

Additionally, unify freepage counting code, because it can be done in
common part, __free_one_page(). This unifying provides extra guarantee
that the page on isolate pageblock don't go into non-isolate buddy list.
This is similar situation describing in previous patch so refer it
if you need more explanation.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 include/linux/mmzone.h         |    5 +++++
 include/linux/page-isolation.h |    8 ++++++++
 mm/page_alloc.c                |   40 +++++++++++++++++++---------------------
 mm/page_isolation.c            |    2 ++
 4 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index fd48890..e9c194f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -374,6 +374,11 @@ struct zone {
 	/* pfn where async and sync compaction migration scanner should start */
 	unsigned long		compact_cached_migrate_pfn[2];
 #endif
+
+#ifdef CONFIG_MEMORY_ISOLATION
+	unsigned long		nr_isolate_pageblock;
+#endif
+
 #ifdef CONFIG_MEMORY_HOTPLUG
 	/* see spanned/present_pages for more description */
 	seqlock_t		span_seqlock;
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 3fff8e7..2dc1e16 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -2,6 +2,10 @@
 #define __LINUX_PAGEISOLATION_H
 
 #ifdef CONFIG_MEMORY_ISOLATION
+static inline bool has_isolate_pageblock(struct zone *zone)
+{
+	return zone->nr_isolate_pageblock;
+}
 static inline bool is_migrate_isolate_page(struct page *page)
 {
 	return get_pageblock_migratetype(page) == MIGRATE_ISOLATE;
@@ -11,6 +15,10 @@ static inline bool is_migrate_isolate(int migratetype)
 	return migratetype == MIGRATE_ISOLATE;
 }
 #else
+static inline bool has_isolate_pageblock(struct zone *zone)
+{
+	return false;
+}
 static inline bool is_migrate_isolate_page(struct page *page)
 {
 	return false;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d8feedc..dcc2f08 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -594,6 +594,24 @@ static inline void __free_one_page(struct page *page,
 	VM_BUG_ON_PAGE(page_idx & ((1 << order) - 1), page);
 	VM_BUG_ON_PAGE(bad_range(zone, page), page);
 
+	/*
+	 * pcp pages could go normal buddy list due to stale pageblock
+	 * migratetype so re-check it if there is isolate pageblock.
+	 *
+	 * And, we got migratetype without holding the lock so it could be
+	 * racy. If some pages go on the isolate migratetype buddy list
+	 * by this race, we can't allocate this page anymore until next
+	 * isolation attempt on this pageblock. To prevent this
+	 * possibility, re-check migratetype with holding the lock.
+	 */
+	if (unlikely(has_isolate_pageblock(zone) ||
+		is_migrate_isolate(migratetype))) {
+		migratetype = get_pfnblock_migratetype(page, pfn);
+	}
+
+	if (!is_migrate_isolate(migratetype))
+		__mod_zone_freepage_state(zone, 1 << order, migratetype);
+
 	while (order < MAX_ORDER-1) {
 		buddy_idx = __find_buddy_index(page_idx, order);
 		buddy = page + (buddy_idx - page_idx);
@@ -719,13 +737,7 @@ static void free_pcppages_bulk(struct zone *zone, int count,
 			page = list_entry(list->prev, struct page, lru);
 			/* must delete as __free_one_page list manipulates */
 			list_del(&page->lru);
-
-			if (unlikely(is_migrate_isolate_page(page))) {
-				mt = MIGRATE_ISOLATE;
-			} else {
-				mt = get_freepage_migratetype(page);
-				__mod_zone_freepage_state(zone, 1, mt);
-			}
+			mt = get_freepage_migratetype(page);
 
 			/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
 			__free_one_page(page, page_to_pfn(page), zone, 0, mt);
@@ -742,21 +754,7 @@ static void free_one_page(struct zone *zone,
 {
 	spin_lock(&zone->lock);
 	zone->pages_scanned = 0;
-
-	if (unlikely(is_migrate_isolate(migratetype))) {
-		/*
-		 * We got migratetype without holding the lock so it could be
-		 * racy. If some pages go on the isolate migratetype buddy list
-		 * by this race, we can't allocate this page anymore until next
-		 * isolation attempt on this pageblock. To prevent this
-		 * possibility, re-check migratetype with holding the lock.
-		 */
-		migratetype = get_pfnblock_migratetype(page, pfn);
-	}
-
 	__free_one_page(page, pfn, zone, order, migratetype);
-	if (!is_migrate_isolate(migratetype))
-		__mod_zone_freepage_state(zone, 1 << order, migratetype);
 	spin_unlock(&zone->lock);
 }
 
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index d1473b2..1fa4a4d 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -60,6 +60,7 @@ out:
 		int migratetype = get_pageblock_migratetype(page);
 
 		set_pageblock_migratetype(page, MIGRATE_ISOLATE);
+		zone->nr_isolate_pageblock++;
 		nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE);
 
 		__mod_zone_freepage_state(zone, -nr_pages, migratetype);
@@ -83,6 +84,7 @@ void unset_migratetype_isolate(struct page *page, unsigned migratetype)
 	nr_pages = move_freepages_block(zone, page, migratetype);
 	__mod_zone_freepage_state(zone, nr_pages, migratetype);
 	set_pageblock_migratetype(page, migratetype);
+	zone->nr_isolate_pageblock--;
 out:
 	spin_unlock_irqrestore(&zone->lock, flags);
 }
-- 
1.7.9.5


  parent reply	other threads:[~2014-07-04  7:52 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-04  7:57 [PATCH 00/10] fix freepage count problems due to memory isolation Joonsoo Kim
2014-07-04  7:57 ` [PATCH 01/10] mm/page_alloc: remove unlikely macro on free_one_page() Joonsoo Kim
2014-07-04 12:03   ` Vlastimil Babka
2014-07-07  4:58     ` Joonsoo Kim
2014-07-04 12:52   ` Michal Nazarewicz
2014-07-04 12:53   ` Michal Nazarewicz
2014-07-04  7:57 ` [PATCH 02/10] mm/page_alloc: correct to clear guard attribute in DEBUG_PAGEALLOC Joonsoo Kim
2014-07-07 14:50   ` Vlastimil Babka
2014-07-04  7:57 ` [PATCH 03/10] mm/page_alloc: handle page on pcp correctly if it's pageblock is isolated Joonsoo Kim
2014-07-07  8:25   ` Gioh Kim
2014-07-08  7:18     ` Vlastimil Babka
2014-07-07 15:19   ` Vlastimil Babka
2014-07-14  6:24     ` Joonsoo Kim
2014-07-04  7:57 ` [PATCH 04/10] mm/page_alloc: carefully free the page on isolate pageblock Joonsoo Kim
2014-07-07 15:43   ` Vlastimil Babka
2014-07-04  7:57 ` Joonsoo Kim [this message]
2014-07-07 15:50   ` [PATCH 05/10] mm/page_alloc: optimize and unify pageblock migratetype check in free path Vlastimil Babka
2014-07-14  6:28     ` Joonsoo Kim
2014-07-04  7:57 ` [PATCH 06/10] mm/page_alloc: separate freepage migratetype interface Joonsoo Kim
2014-07-04  7:57 ` [PATCH 07/10] mm/page_alloc: store migratetype of the buddy list into freepage correctly Joonsoo Kim
2014-07-04  7:57 ` [PATCH 08/10] mm/page_alloc: use get_onbuddy_migratetype() to get buddy list type Joonsoo Kim
2014-07-07 15:57   ` Vlastimil Babka
2014-07-08  1:01     ` Gioh Kim
2014-07-08  7:23       ` Vlastimil Babka
2014-07-14  6:34     ` Joonsoo Kim
2014-07-04  7:57 ` [PATCH 09/10] mm/page_alloc: fix possible wrongly calculated freepage counter Joonsoo Kim
2014-07-04  7:57 ` [PATCH 10/10] mm/page_alloc: Stop merging pages on non-isolate and isolate buddy list Joonsoo Kim
2014-07-04 15:33 ` [PATCH 00/10] fix freepage count problems due to memory isolation Vlastimil Babka
2014-07-07  4:49   ` Joonsoo Kim
2014-07-07 14:33     ` Vlastimil Babka
2014-07-14  6:22       ` Joonsoo Kim
2014-07-14  9:49         ` Vlastimil Babka
2014-07-15  8:28           ` Joonsoo Kim
2014-07-15  8:36             ` Vlastimil Babka
2014-07-16  8:43               ` Joonsoo Kim
2014-07-16 11:14                 ` Vlastimil Babka
2014-07-17  6:12                   ` Joonsoo Kim
2014-07-17  9:14                     ` Vlastimil Babka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1404460675-24456-6-git-send-email-iamjoonsoo.kim@lge.com \
    --to=iamjoonsoo.kim@lge.com \
    --cc=akpm@linux-foundation.org \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=gioh.kim@lge.com \
    --cc=hannes@cmpxchg.org \
    --cc=heesub.shin@samsung.com \
    --cc=isimatu.yasuaki@jp.fujitsu.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=lauraa@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mgorman@suse.de \
    --cc=mina86@mina86.com \
    --cc=minchan@kernel.org \
    --cc=n-horiguchi@ah.jp.nec.com \
    --cc=peterz@infradead.org \
    --cc=riel@redhat.com \
    --cc=ritesh.list@gmail.com \
    --cc=srivatsa.bhat@linux.vnet.ibm.com \
    --cc=t.stanislaws@samsung.com \
    --cc=tangchen@cn.fujitsu.com \
    --cc=wency@cn.fujitsu.com \
    --cc=zhangyanfei@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).