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


Groups > linux.kernel > #1424776 > unrolled thread

[PATCH v3 0/9] reduce memory usage by page_owner

Started byjs1304@gmail.com
First post2016-06-17 10:00 +0200
Last post2016-06-17 10:10 +0200
Articles 7 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/9] reduce memory usage by page_owner js1304@gmail.com - 2016-06-17 10:00 +0200
    [PATCH v3 9/9] mm/page_isolation: clean up confused code js1304@gmail.com - 2016-06-17 10:00 +0200
      Re: [PATCH v3 9/9] mm/page_isolation: clean up confused code Vlastimil Babka <vbabka@suse.cz> - 2016-06-17 15:40 +0200
    [PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer size js1304@gmail.com - 2016-06-17 10:00 +0200
      Re: [PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer  size Vlastimil Babka <vbabka@suse.cz> - 2016-06-17 15:00 +0200
    [PATCH v3 1/9] mm/compaction: split freepages without holding the zone lock js1304@gmail.com - 2016-06-17 10:10 +0200
    [PATCH v3 3/9] mm/page_owner: copy last_migrate_reason in copy_page_owner() js1304@gmail.com - 2016-06-17 10:10 +0200

#1424776 — [PATCH v3 0/9] reduce memory usage by page_owner

Fromjs1304@gmail.com
Date2016-06-17 10:00 +0200
Subject[PATCH v3 0/9] reduce memory usage by page_owner
Message-ID<rKWR3-3Hd-3@gated-at.bofh.it>
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Hello,

There was a bug reported by Sasha and minor fixes is needed
so I send v3.

o fix a bg reported by Sasha (mm/compaction: split freepages
without holding the zone lock)
o add code comment for todo list (mm/page_owner: use stackdepot
to store stacktrace) per Michal
o add 'inline' keyword (mm/page_alloc: introduce post allocation
processing on page allocator) per Vlastimil
o add a patch that clean-up code per Vlastimil

Joonsoo Kim (8):
  mm/compaction: split freepages without holding the zone lock
  mm/page_owner: initialize page owner without holding the zone lock
  mm/page_owner: copy last_migrate_reason in copy_page_owner()
  mm/page_owner: introduce split_page_owner and replace manual handling
  tools/vm/page_owner: increase temporary buffer size
  mm/page_owner: use stackdepot to store stacktrace
  mm/page_alloc: introduce post allocation processing on page allocator
  mm/page_isolation: clean up confused code

Sudip Mukherjee (1):
  mm/page_owner: avoid null pointer dereference

 include/linux/mm.h         |   1 -
 include/linux/page_ext.h   |   4 +-
 include/linux/page_owner.h |  12 ++--
 lib/Kconfig.debug          |   1 +
 mm/compaction.c            |  44 ++++++++----
 mm/internal.h              |   2 +
 mm/page_alloc.c            |  60 +++++------------
 mm/page_isolation.c        |  13 ++--
 mm/page_owner.c            | 163 +++++++++++++++++++++++++++++++++++++--------
 tools/vm/page_owner_sort.c |   9 ++-
 10 files changed, 205 insertions(+), 104 deletions(-)

-- 
1.9.1

[toc] | [next] | [standalone]


#1424777 — [PATCH v3 9/9] mm/page_isolation: clean up confused code

Fromjs1304@gmail.com
Date2016-06-17 10:00 +0200
Subject[PATCH v3 9/9] mm/page_isolation: clean up confused code
Message-ID<rKWR4-3Hd-39@gated-at.bofh.it>
In reply to#1424776
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>

When there is an isolated_page, post_alloc_hook() is called with
page but __free_pages() is called with isolated_page. Since they are
the same so no problem but it's very confusing. To reduce it,
this patch changes isolated_page to boolean type and uses page variable
consistently.

Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
---
 mm/page_isolation.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 4639163..064b7fb 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -81,7 +81,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
 {
 	struct zone *zone;
 	unsigned long flags, nr_pages;
-	struct page *isolated_page = NULL;
+	bool isolated_page = false;
 	unsigned int order;
 	unsigned long page_idx, buddy_idx;
 	struct page *buddy;
@@ -109,7 +109,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
 			if (pfn_valid_within(page_to_pfn(buddy)) &&
 			    !is_migrate_isolate_page(buddy)) {
 				__isolate_free_page(page, order);
-				isolated_page = page;
+				isolated_page = true;
 			}
 		}
 	}
@@ -129,7 +129,7 @@ out:
 	spin_unlock_irqrestore(&zone->lock, flags);
 	if (isolated_page) {
 		post_alloc_hook(page, order, __GFP_MOVABLE);
-		__free_pages(isolated_page, order);
+		__free_pages(page, order);
 	}
 }
 
-- 
1.9.1

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


#1425089 — Re: [PATCH v3 9/9] mm/page_isolation: clean up confused code

FromVlastimil Babka <vbabka@suse.cz>
Date2016-06-17 15:40 +0200
SubjectRe: [PATCH v3 9/9] mm/page_isolation: clean up confused code
Message-ID<rL2a6-77b-13@gated-at.bofh.it>
In reply to#1424777
On 06/17/2016 09:57 AM, js1304@gmail.com wrote:
> From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
>
> When there is an isolated_page, post_alloc_hook() is called with
> page but __free_pages() is called with isolated_page. Since they are
> the same so no problem but it's very confusing. To reduce it,
> this patch changes isolated_page to boolean type and uses page variable
> consistently.
>
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

Could be also just folded to mm/page_owner: initialize page owner without 
holding the zone lock

> ---
>  mm/page_isolation.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/mm/page_isolation.c b/mm/page_isolation.c
> index 4639163..064b7fb 100644
> --- a/mm/page_isolation.c
> +++ b/mm/page_isolation.c
> @@ -81,7 +81,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
>  {
>  	struct zone *zone;
>  	unsigned long flags, nr_pages;
> -	struct page *isolated_page = NULL;
> +	bool isolated_page = false;
>  	unsigned int order;
>  	unsigned long page_idx, buddy_idx;
>  	struct page *buddy;
> @@ -109,7 +109,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype)
>  			if (pfn_valid_within(page_to_pfn(buddy)) &&
>  			    !is_migrate_isolate_page(buddy)) {
>  				__isolate_free_page(page, order);
> -				isolated_page = page;
> +				isolated_page = true;
>  			}
>  		}
>  	}
> @@ -129,7 +129,7 @@ out:
>  	spin_unlock_irqrestore(&zone->lock, flags);
>  	if (isolated_page) {
>  		post_alloc_hook(page, order, __GFP_MOVABLE);
> -		__free_pages(isolated_page, order);
> +		__free_pages(page, order);
>  	}
>  }
>
>

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


#1424778 — [PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer size

Fromjs1304@gmail.com
Date2016-06-17 10:00 +0200
Subject[PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer size
Message-ID<rKWR4-3Hd-41@gated-at.bofh.it>
In reply to#1424776
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Page owner will be changed to store more deep stacktrace so current
temporary buffer size isn't enough.  Increase it.

Link: http://lkml.kernel.org/r/1464230275-25791-5-git-send-email-iamjoonsoo.kim@lge.com
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Alexander Potapenko <glider@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Michal Hocko <mhocko@kernel.org>
---
 tools/vm/page_owner_sort.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c
index 77147b4..f1c055f 100644
--- a/tools/vm/page_owner_sort.c
+++ b/tools/vm/page_owner_sort.c
@@ -79,12 +79,12 @@ static void add_list(char *buf, int len)
 	}
 }
 
-#define BUF_SIZE	1024
+#define BUF_SIZE	(128 * 1024)
 
 int main(int argc, char **argv)
 {
 	FILE *fin, *fout;
-	char buf[BUF_SIZE];
+	char *buf;
 	int ret, i, count;
 	struct block_list *list2;
 	struct stat st;
@@ -107,6 +107,11 @@ int main(int argc, char **argv)
 	max_size = st.st_size / 100; /* hack ... */
 
 	list = malloc(max_size * sizeof(*list));
+	buf = malloc(BUF_SIZE);
+	if (!list || !buf) {
+		printf("Out of memory\n");
+		exit(1);
+	}
 
 	for ( ; ; ) {
 		ret = read_block(buf, BUF_SIZE, fin);
-- 
1.9.1

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


#1425049 — Re: [PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer size

FromVlastimil Babka <vbabka@suse.cz>
Date2016-06-17 15:00 +0200
SubjectRe: [PATCH v3 5/9] tools/vm/page_owner: increase temporary buffer size
Message-ID<rL1xo-6DO-19@gated-at.bofh.it>
In reply to#1424778
On 06/17/2016 09:57 AM, js1304@gmail.com wrote:
> From: Joonsoo Kim <iamjoonsoo.kim@lge.com>
>
> Page owner will be changed to store more deep stacktrace so current
> temporary buffer size isn't enough.  Increase it.
>
> Link: http://lkml.kernel.org/r/1464230275-25791-5-git-send-email-iamjoonsoo.kim@lge.com
> Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
> Cc: Vlastimil Babka <vbabka@suse.cz>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

> Cc: Mel Gorman <mgorman@techsingularity.net>
> Cc: Minchan Kim <minchan@kernel.org>
> Cc: Alexander Potapenko <glider@google.com>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: Michal Hocko <mhocko@kernel.org>
> ---
>  tools/vm/page_owner_sort.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c
> index 77147b4..f1c055f 100644
> --- a/tools/vm/page_owner_sort.c
> +++ b/tools/vm/page_owner_sort.c
> @@ -79,12 +79,12 @@ static void add_list(char *buf, int len)
>  	}
>  }
>
> -#define BUF_SIZE	1024
> +#define BUF_SIZE	(128 * 1024)
>
>  int main(int argc, char **argv)
>  {
>  	FILE *fin, *fout;
> -	char buf[BUF_SIZE];
> +	char *buf;
>  	int ret, i, count;
>  	struct block_list *list2;
>  	struct stat st;
> @@ -107,6 +107,11 @@ int main(int argc, char **argv)
>  	max_size = st.st_size / 100; /* hack ... */
>
>  	list = malloc(max_size * sizeof(*list));
> +	buf = malloc(BUF_SIZE);
> +	if (!list || !buf) {
> +		printf("Out of memory\n");
> +		exit(1);
> +	}
>
>  	for ( ; ; ) {
>  		ret = read_block(buf, BUF_SIZE, fin);
>

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


#1424786 — [PATCH v3 1/9] mm/compaction: split freepages without holding the zone lock

Fromjs1304@gmail.com
Date2016-06-17 10:10 +0200
Subject[PATCH v3 1/9] mm/compaction: split freepages without holding the zone lock
Message-ID<rKX0K-3ZY-17@gated-at.bofh.it>
In reply to#1424776
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>

We don't need to split freepages with holding the zone lock.  It will
cause more contention on zone lock so not desirable.

v3: fix un-isolated case

Link: http://lkml.kernel.org/r/1464230275-25791-1-git-send-email-iamjoonsoo.kim@lge.com
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Alexander Potapenko <glider@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Michal Hocko <mhocko@kernel.org>
---
 include/linux/mm.h |  1 -
 mm/compaction.c    | 47 +++++++++++++++++++++++++++++++++--------------
 mm/page_alloc.c    | 27 ---------------------------
 3 files changed, 33 insertions(+), 42 deletions(-)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 558949e..15b3bc9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -562,7 +562,6 @@ void __put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
 void split_page(struct page *page, unsigned int order);
-int split_free_page(struct page *page);
 
 /*
  * Compound pages have a destructor function.  Provide a
diff --git a/mm/compaction.c b/mm/compaction.c
index d1d2063..5557421 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -64,13 +64,31 @@ static unsigned long release_freepages(struct list_head *freelist)
 
 static void map_pages(struct list_head *list)
 {
-	struct page *page;
+	unsigned int i, order, nr_pages;
+	struct page *page, *next;
+	LIST_HEAD(tmp_list);
+
+	list_for_each_entry_safe(page, next, list, lru) {
+		list_del(&page->lru);
 
-	list_for_each_entry(page, list, lru) {
-		arch_alloc_page(page, 0);
-		kernel_map_pages(page, 1, 1);
-		kasan_alloc_pages(page, 0);
+		order = page_private(page);
+		nr_pages = 1 << order;
+		set_page_private(page, 0);
+		set_page_refcounted(page);
+
+		arch_alloc_page(page, order);
+		kernel_map_pages(page, nr_pages, 1);
+		kasan_alloc_pages(page, order);
+		if (order)
+			split_page(page, order);
+
+		for (i = 0; i < nr_pages; i++) {
+			list_add(&page->lru, &tmp_list);
+			page++;
+		}
 	}
+
+	list_splice(&tmp_list, list);
 }
 
 static inline bool migrate_async_suitable(int migratetype)
@@ -405,12 +423,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 	unsigned long flags = 0;
 	bool locked = false;
 	unsigned long blockpfn = *start_pfn;
+	unsigned int order;
 
 	cursor = pfn_to_page(blockpfn);
 
 	/* Isolate free pages. */
 	for (; blockpfn < end_pfn; blockpfn++, cursor++) {
-		int isolated, i;
+		int isolated;
 		struct page *page = cursor;
 
 		/*
@@ -476,16 +495,16 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
 				goto isolate_fail;
 		}
 
-		/* Found a free page, break it into order-0 pages */
-		isolated = split_free_page(page);
-		total_isolated += isolated;
-		for (i = 0; i < isolated; i++) {
-			list_add(&page->lru, freelist);
-			page++;
-		}
+		/* Found a free page, will break it into order-0 pages */
+		order = page_order(page);
+		isolated = __isolate_free_page(page, order);
 
-		/* If a page was split, advance to the end of it */
+		/* If a page was isolated, advance to the end of it */
 		if (isolated) {
+			set_page_private(page, order);
+			total_isolated += isolated;
+			list_add_tail(&page->lru, freelist);
+
 			cc->nr_freepages += isolated;
 			if (!strict &&
 				cc->nr_migratepages <= cc->nr_freepages) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e08186a..e07f424 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2532,33 +2532,6 @@ int __isolate_free_page(struct page *page, unsigned int order)
 }
 
 /*
- * Similar to split_page except the page is already free. As this is only
- * being used for migration, the migratetype of the block also changes.
- * As this is called with interrupts disabled, the caller is responsible
- * for calling arch_alloc_page() and kernel_map_page() after interrupts
- * are enabled.
- *
- * Note: this is probably too low level an operation for use in drivers.
- * Please consult with lkml before using this in your driver.
- */
-int split_free_page(struct page *page)
-{
-	unsigned int order;
-	int nr_pages;
-
-	order = page_order(page);
-
-	nr_pages = __isolate_free_page(page, order);
-	if (!nr_pages)
-		return 0;
-
-	/* Split into individual pages */
-	set_page_refcounted(page);
-	split_page(page, order);
-	return nr_pages;
-}
-
-/*
  * Update NUMA hit/miss statistics
  *
  * Must be called with interrupts disabled.
-- 
1.9.1

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


#1424790 — [PATCH v3 3/9] mm/page_owner: copy last_migrate_reason in copy_page_owner()

Fromjs1304@gmail.com
Date2016-06-17 10:10 +0200
Subject[PATCH v3 3/9] mm/page_owner: copy last_migrate_reason in copy_page_owner()
Message-ID<rKX0L-3ZY-33@gated-at.bofh.it>
In reply to#1424776
From: Joonsoo Kim <iamjoonsoo.kim@lge.com>

Currently, copy_page_owner() doesn't copy all the owner information.  It
skips last_migrate_reason because copy_page_owner() is used for migration
and it will be properly set soon.  But, following patch will use
copy_page_owner() and this skip will cause the problem that allocated page
has uninitialied last_migrate_reason.  To prevent it, this patch also copy
last_migrate_reason in copy_page_owner().

Link: http://lkml.kernel.org/r/1464230275-25791-3-git-send-email-iamjoonsoo.kim@lge.com
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Alexander Potapenko <glider@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Michal Hocko <mhocko@kernel.org>
---
 mm/page_owner.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/page_owner.c b/mm/page_owner.c
index c6cda3e..73e202f 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -118,6 +118,7 @@ void __copy_page_owner(struct page *oldpage, struct page *newpage)
 
 	new_ext->order = old_ext->order;
 	new_ext->gfp_mask = old_ext->gfp_mask;
+	new_ext->last_migrate_reason = old_ext->last_migrate_reason;
 	new_ext->nr_entries = old_ext->nr_entries;
 
 	for (i = 0; i < ARRAY_SIZE(new_ext->trace_entries); i++)
-- 
1.9.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web