Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1262329 > unrolled thread
| Started by | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| First post | 2015-11-04 16:10 +0100 |
| Last post | 2015-11-04 16:10 +0100 |
| Articles | 11 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH 0/5] page_owner improvements for debugging Vlastimil Babka <vbabka@suse.cz> - 2015-11-04 16:10 +0100
[PATCH 4/5] mm, page_owner: track last migrate reason Vlastimil Babka <vbabka@suse.cz> - 2015-11-04 16:10 +0100
[PATCH 5/5] mm, page_owner: dump page owner info from dump_page() Vlastimil Babka <vbabka@suse.cz> - 2015-11-04 16:10 +0100
Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() "Kirill A. Shutemov" <kirill@shutemov.name> - 2015-11-04 20:50 +0100
Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() Sasha Levin <sasha.levin@oracle.com> - 2015-11-04 21:20 +0100
Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() "Kirill A. Shutemov" <kirill@shutemov.name> - 2015-11-04 21:50 +0100
[PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock Vlastimil Babka <vbabka@suse.cz> - 2015-11-04 16:10 +0100
Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock Joonsoo Kim <iamjoonsoo.kim@lge.com> - 2015-11-05 09:10 +0100
Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock Joonsoo Kim <iamjoonsoo.kim@lge.com> - 2015-11-05 09:20 +0100
Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock Vlastimil Babka <vbabka@suse.cz> - 2015-11-05 09:20 +0100
[PATCH 2/5] mm, page_owner: convert page_owner_inited to static key Vlastimil Babka <vbabka@suse.cz> - 2015-11-04 16:10 +0100
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-04 16:10 +0100 |
| Subject | [PATCH 0/5] page_owner improvements for debugging |
| Message-ID | <qr7Rf-24F-3@gated-at.bofh.it> |
Hi, I know it's merge window, but this might potentially help us with some outstanding bugs if page_owner was enabled e.g. for trinity runs, so here you go. Patch 1 is a bug fix, patch 2 reduces page_owner overhead when compiled in but not enabled on boot. Patch 3 is something I suggested before [1] and it was deemed a good idea, that the page_owner info should follow the page during migration. Patch 4 allows us again to know that a migration happened and for which reason. Patch 5 will hopefully help us when debugging, as it makes all the info be printed as part of e.g. VM_BUG_ON_PAGE(). Until now it was only accessible via /sys file. Patches are based on today's -next. Hugh's migration patches caused conflicts for patches 3 and 4 when rebasing from 4.3. [1] https://lkml.org/lkml/2015/7/23/47 Vlastimil Babka (5): mm, page_owner: print migratetype of a page, not pageblock mm, page_owner: convert page_owner_inited to static key mm, page_owner: copy page owner info during migration mm, page_owner: track last migrate reason mm, page_owner: dump page owner info from dump_page() Documentation/vm/page_owner.txt | 9 +++--- include/linux/page_ext.h | 1 + include/linux/page_owner.h | 50 ++++++++++++++++++++++++--------- mm/debug.c | 2 ++ mm/migrate.c | 11 ++++++-- mm/page_owner.c | 61 +++++++++++++++++++++++++++++++++++++---- mm/vmstat.c | 2 +- 7 files changed, 110 insertions(+), 26 deletions(-) -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-04 16:10 +0100 |
| Subject | [PATCH 4/5] mm, page_owner: track last migrate reason |
| Message-ID | <qr7Rf-24F-11@gated-at.bofh.it> |
| In reply to | #1262329 |
During migration, page_owner info is now copied with the rest of the page, so
the stacktrace leading to free page allocation during migration is overwritten.
For debugging purposes, it might be however useful to know that the page has
been migrated since its initial allocation. This might happen many times during
the lifetime for different reasons, and fully tracking this, especially with
stacktraces would incur extra memory costs. As a compromise, store the
migrate_reason of the last migration that occurred to the page. This is enough
to distinguish compaction, numa balancing etc.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
include/linux/page_ext.h | 1 +
include/linux/page_owner.h | 9 +++++++++
mm/migrate.c | 9 ++++++---
mm/page_owner.c | 16 ++++++++++++++++
4 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h
index 17f118a..e1fe7cf 100644
--- a/include/linux/page_ext.h
+++ b/include/linux/page_ext.h
@@ -45,6 +45,7 @@ struct page_ext {
unsigned int order;
gfp_t gfp_mask;
unsigned int nr_entries;
+ int last_migrate_reason;
unsigned long trace_entries[8];
#endif
};
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 6440daa..555893b 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -12,6 +12,7 @@ extern void __set_page_owner(struct page *page,
unsigned int order, gfp_t gfp_mask);
extern gfp_t __get_page_owner_gfp(struct page *page);
extern void __copy_page_owner(struct page *oldpage, struct page *newpage);
+extern void __set_page_owner_migrate_reason(struct page *page, int reason);
static inline void reset_page_owner(struct page *page, unsigned int order)
{
@@ -38,6 +39,11 @@ static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
if (static_branch_unlikely(&page_owner_inited))
__copy_page_owner(oldpage, newpage);
}
+static inline void set_page_owner_migrate_reason(struct page *page, int reason)
+{
+ if (static_branch_unlikely(&page_owner_inited))
+ __set_page_owner_migrate_reason(page, reason);
+}
#else
static inline void reset_page_owner(struct page *page, unsigned int order)
{
@@ -53,5 +59,8 @@ static inline gfp_t get_page_owner_gfp(struct page *page)
static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
{
}
+static inline void set_page_owner_migrate_reason(struct page *page, int reason)
+{
+}
#endif /* CONFIG_PAGE_OWNER */
#endif /* __LINUX_PAGE_OWNER_H */
diff --git a/mm/migrate.c b/mm/migrate.c
index 9f82e03..5a4fb1f 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -954,8 +954,10 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
}
rc = __unmap_and_move(page, newpage, force, mode);
- if (rc == MIGRATEPAGE_SUCCESS)
+ if (rc == MIGRATEPAGE_SUCCESS) {
put_new_page = NULL;
+ set_page_owner_migrate_reason(newpage, reason);
+ }
out:
if (rc != -EAGAIN) {
@@ -1020,7 +1022,7 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
static int unmap_and_move_huge_page(new_page_t get_new_page,
free_page_t put_new_page, unsigned long private,
struct page *hpage, int force,
- enum migrate_mode mode)
+ enum migrate_mode mode, int reason)
{
int rc = -EAGAIN;
int *result = NULL;
@@ -1078,6 +1080,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
if (rc == MIGRATEPAGE_SUCCESS) {
hugetlb_cgroup_migrate(hpage, new_hpage);
put_new_page = NULL;
+ set_page_owner_migrate_reason(new_hpage, reason);
}
unlock_page(hpage);
@@ -1150,7 +1153,7 @@ int migrate_pages(struct list_head *from, new_page_t get_new_page,
if (PageHuge(page))
rc = unmap_and_move_huge_page(get_new_page,
put_new_page, private, page,
- pass > 2, mode);
+ pass > 2, mode, reason);
else
rc = unmap_and_move(get_new_page, put_new_page,
private, page, pass > 2, mode,
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 7ebd3d0..388898f 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -73,10 +73,18 @@ void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask)
page_ext->order = order;
page_ext->gfp_mask = gfp_mask;
page_ext->nr_entries = trace.nr_entries;
+ page_ext->last_migrate_reason = -1;
__set_bit(PAGE_EXT_OWNER, &page_ext->flags);
}
+void __set_page_owner_migrate_reason(struct page *page, int reason)
+{
+ struct page_ext *page_ext = lookup_page_ext(page);
+
+ page_ext->last_migrate_reason = reason;
+}
+
gfp_t __get_page_owner_gfp(struct page *page)
{
struct page_ext *page_ext = lookup_page_ext(page);
@@ -152,6 +160,14 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
if (ret >= count)
goto err;
+ if (page_ext->last_migrate_reason != -1) {
+ ret += snprintf(kbuf + ret, count - ret,
+ "Page has been migrated, last migrate reason: %d\n",
+ page_ext->last_migrate_reason);
+ if (ret >= count)
+ goto err;
+ }
+
ret += snprintf(kbuf + ret, count - ret, "\n");
if (ret >= count)
goto err;
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-04 16:10 +0100 |
| Subject | [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() |
| Message-ID | <qr7Rg-24F-15@gated-at.bofh.it> |
| In reply to | #1262329 |
The page_owner mechanism is useful for dealing with memory leaks. By reading
/sys/kernel/debug/page_owner one can determine the stack traces leading to
allocations of all pages, and find e.g. a buggy driver.
This information might be also potentially useful for debugging, such as the
VM_BUG_ON_PAGE() calls to dump_page(). So let's print the stored info from
dump_page().
Example output:
[ 199.188777] page:ffffea0002900540 count:2 mapcount:0 mapping:ffff880131993e18 index:0x34e
[ 199.202832] flags: 0x1fffff80020048(uptodate|active|mappedtodisk)
[ 199.207048] page dumped because: VM_BUG_ON_PAGE(1)
[ 199.207048] page->mem_cgroup:ffff880138efdc00
[ 199.207050] page allocated via order 0, mask 0x213da, migratetype 2, trace:
[ 199.207050] [<ffffffff811622c5>] __alloc_pages_nodemask+0x175/0x900
[ 199.207057] [<ffffffff811a69c1>] alloc_pages_current+0x91/0x100
[ 199.207061] [<ffffffff81158da1>] __page_cache_alloc+0xb1/0xf0
[ 199.207066] [<ffffffff81165eeb>] __do_page_cache_readahead+0xdb/0x200
[ 199.207067] [<ffffffff81166155>] ondemand_readahead+0x145/0x270
[ 199.207069] [<ffffffff811662ec>] page_cache_async_readahead+0x6c/0x70
[ 199.207070] [<ffffffff8115a838>] generic_file_read_iter+0x378/0x590
[ 199.207074] [<ffffffff811cd2d7>] __vfs_read+0xa7/0xd0
[ 199.207074] page has been migrated, last migrate reason: 0
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
include/linux/page_owner.h | 9 +++++++++
mm/debug.c | 2 ++
mm/page_owner.c | 18 ++++++++++++++++++
3 files changed, 29 insertions(+)
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 555893b..46f1b93 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -13,6 +13,7 @@ extern void __set_page_owner(struct page *page,
extern gfp_t __get_page_owner_gfp(struct page *page);
extern void __copy_page_owner(struct page *oldpage, struct page *newpage);
extern void __set_page_owner_migrate_reason(struct page *page, int reason);
+extern void __dump_page_owner(struct page *page);
static inline void reset_page_owner(struct page *page, unsigned int order)
{
@@ -44,6 +45,11 @@ static inline void set_page_owner_migrate_reason(struct page *page, int reason)
if (static_branch_unlikely(&page_owner_inited))
__set_page_owner_migrate_reason(page, reason);
}
+static inline void dump_page_owner(struct page *page)
+{
+ if (static_branch_unlikely(&page_owner_inited))
+ __dump_page_owner(page);
+}
#else
static inline void reset_page_owner(struct page *page, unsigned int order)
{
@@ -62,5 +68,8 @@ static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
static inline void set_page_owner_migrate_reason(struct page *page, int reason)
{
}
+static inline void dump_page_owner(struct page *page)
+{
+}
#endif /* CONFIG_PAGE_OWNER */
#endif /* __LINUX_PAGE_OWNER_H */
diff --git a/mm/debug.c b/mm/debug.c
index 8362765..93373d1 100644
--- a/mm/debug.c
+++ b/mm/debug.c
@@ -9,6 +9,7 @@
#include <linux/mm.h>
#include <linux/trace_events.h>
#include <linux/memcontrol.h>
+#include <linux/page_owner.h>
static const struct trace_print_flags pageflag_names[] = {
{1UL << PG_locked, "locked" },
@@ -98,6 +99,7 @@ void dump_page_badflags(struct page *page, const char *reason,
if (page->mem_cgroup)
pr_alert("page->mem_cgroup:%p\n", page->mem_cgroup);
#endif
+ dump_page_owner(page);
}
void dump_page(struct page *page, const char *reason)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 388898f..d7e0aaf 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -183,6 +183,24 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
return -ENOMEM;
}
+void __dump_page_owner(struct page *page)
+{
+ struct page_ext *page_ext = lookup_page_ext(page);
+ struct stack_trace trace = {
+ .nr_entries = page_ext->nr_entries,
+ .entries = &page_ext->trace_entries[0],
+ };
+
+ pr_alert("page allocated via order %u, mask 0x%x, migratetype %d, trace:\n",
+ page_ext->order, page_ext->gfp_mask,
+ gfpflags_to_migratetype(page_ext->gfp_mask));
+ print_stack_trace(&trace, 0);
+
+ if (page_ext->last_migrate_reason != -1)
+ pr_alert("page has been migrated, last migrate reason: %d\n",
+ page_ext->last_migrate_reason);
+}
+
static ssize_t
read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill@shutemov.name> |
|---|---|
| Date | 2015-11-04 20:50 +0100 |
| Subject | Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() |
| Message-ID | <qrcee-4Ne-17@gated-at.bofh.it> |
| In reply to | #1262334 |
On Wed, Nov 04, 2015 at 04:01:01PM +0100, Vlastimil Babka wrote:
> The page_owner mechanism is useful for dealing with memory leaks. By reading
> /sys/kernel/debug/page_owner one can determine the stack traces leading to
> allocations of all pages, and find e.g. a buggy driver.
>
> This information might be also potentially useful for debugging, such as the
> VM_BUG_ON_PAGE() calls to dump_page(). So let's print the stored info from
> dump_page().
>
> Example output:
>
> [ 199.188777] page:ffffea0002900540 count:2 mapcount:0 mapping:ffff880131993e18 index:0x34e
> [ 199.202832] flags: 0x1fffff80020048(uptodate|active|mappedtodisk)
> [ 199.207048] page dumped because: VM_BUG_ON_PAGE(1)
> [ 199.207048] page->mem_cgroup:ffff880138efdc00
> [ 199.207050] page allocated via order 0, mask 0x213da, migratetype 2, trace:
Can we decode gfp_mask and migratetype into something more human readable?
> [ 199.207050] [<ffffffff811622c5>] __alloc_pages_nodemask+0x175/0x900
> [ 199.207057] [<ffffffff811a69c1>] alloc_pages_current+0x91/0x100
> [ 199.207061] [<ffffffff81158da1>] __page_cache_alloc+0xb1/0xf0
> [ 199.207066] [<ffffffff81165eeb>] __do_page_cache_readahead+0xdb/0x200
> [ 199.207067] [<ffffffff81166155>] ondemand_readahead+0x145/0x270
> [ 199.207069] [<ffffffff811662ec>] page_cache_async_readahead+0x6c/0x70
> [ 199.207070] [<ffffffff8115a838>] generic_file_read_iter+0x378/0x590
> [ 199.207074] [<ffffffff811cd2d7>] __vfs_read+0xa7/0xd0
> [ 199.207074] page has been migrated, last migrate reason: 0
Same here.
>
> Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
> ---
> include/linux/page_owner.h | 9 +++++++++
> mm/debug.c | 2 ++
> mm/page_owner.c | 18 ++++++++++++++++++
> 3 files changed, 29 insertions(+)
>
> diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
> index 555893b..46f1b93 100644
> --- a/include/linux/page_owner.h
> +++ b/include/linux/page_owner.h
> @@ -13,6 +13,7 @@ extern void __set_page_owner(struct page *page,
> extern gfp_t __get_page_owner_gfp(struct page *page);
> extern void __copy_page_owner(struct page *oldpage, struct page *newpage);
> extern void __set_page_owner_migrate_reason(struct page *page, int reason);
> +extern void __dump_page_owner(struct page *page);
>
> static inline void reset_page_owner(struct page *page, unsigned int order)
> {
> @@ -44,6 +45,11 @@ static inline void set_page_owner_migrate_reason(struct page *page, int reason)
> if (static_branch_unlikely(&page_owner_inited))
> __set_page_owner_migrate_reason(page, reason);
> }
> +static inline void dump_page_owner(struct page *page)
> +{
> + if (static_branch_unlikely(&page_owner_inited))
> + __dump_page_owner(page);
> +}
> #else
> static inline void reset_page_owner(struct page *page, unsigned int order)
> {
> @@ -62,5 +68,8 @@ static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
> static inline void set_page_owner_migrate_reason(struct page *page, int reason)
> {
> }
> +static inline void dump_page_owner(struct page *page)
> +{
> +}
> #endif /* CONFIG_PAGE_OWNER */
> #endif /* __LINUX_PAGE_OWNER_H */
> diff --git a/mm/debug.c b/mm/debug.c
> index 8362765..93373d1 100644
> --- a/mm/debug.c
> +++ b/mm/debug.c
> @@ -9,6 +9,7 @@
> #include <linux/mm.h>
> #include <linux/trace_events.h>
> #include <linux/memcontrol.h>
> +#include <linux/page_owner.h>
>
> static const struct trace_print_flags pageflag_names[] = {
> {1UL << PG_locked, "locked" },
> @@ -98,6 +99,7 @@ void dump_page_badflags(struct page *page, const char *reason,
> if (page->mem_cgroup)
> pr_alert("page->mem_cgroup:%p\n", page->mem_cgroup);
> #endif
> + dump_page_owner(page);
I tend to put dump_page() into random places during debug. Dumping page
owner for all dump_page() cases can be too verbose.
Can we introduce dump_page_verbose() which would do usual dump_page() plus
dump_page_owner()?
> }
>
> void dump_page(struct page *page, const char *reason)
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 388898f..d7e0aaf 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -183,6 +183,24 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn,
> return -ENOMEM;
> }
>
> +void __dump_page_owner(struct page *page)
> +{
> + struct page_ext *page_ext = lookup_page_ext(page);
> + struct stack_trace trace = {
> + .nr_entries = page_ext->nr_entries,
> + .entries = &page_ext->trace_entries[0],
> + };
> +
> + pr_alert("page allocated via order %u, mask 0x%x, migratetype %d, trace:\n",
> + page_ext->order, page_ext->gfp_mask,
> + gfpflags_to_migratetype(page_ext->gfp_mask));
> + print_stack_trace(&trace, 0);
> +
> + if (page_ext->last_migrate_reason != -1)
> + pr_alert("page has been migrated, last migrate reason: %d\n",
> + page_ext->last_migrate_reason);
> +}
> +
> static ssize_t
> read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
> {
> --
> 2.6.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
--
Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Sasha Levin <sasha.levin@oracle.com> |
|---|---|
| Date | 2015-11-04 21:20 +0100 |
| Subject | Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() |
| Message-ID | <qrcHh-5df-33@gated-at.bofh.it> |
| In reply to | #1262552 |
On 11/04/2015 02:41 PM, Kirill A. Shutemov wrote: >> + dump_page_owner(page); > I tend to put dump_page() into random places during debug. Dumping page > owner for all dump_page() cases can be too verbose. > > Can we introduce dump_page_verbose() which would do usual dump_page() plus > dump_page_owner()? > Is there any existing piece of code that would use dump_page() rather than dump_page_verbose()? Thanks, Sasha -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Kirill A. Shutemov" <kirill@shutemov.name> |
|---|---|
| Date | 2015-11-04 21:50 +0100 |
| Subject | Re: [PATCH 5/5] mm, page_owner: dump page owner info from dump_page() |
| Message-ID | <qrdah-5oe-3@gated-at.bofh.it> |
| In reply to | #1262571 |
On Wed, Nov 04, 2015 at 03:12:39PM -0500, Sasha Levin wrote: > On 11/04/2015 02:41 PM, Kirill A. Shutemov wrote: > >> + dump_page_owner(page); > > I tend to put dump_page() into random places during debug. Dumping page > > owner for all dump_page() cases can be too verbose. > > > > Can we introduce dump_page_verbose() which would do usual dump_page() plus > > dump_page_owner()? > > > > Is there any existing piece of code that would use dump_page() rather than > dump_page_verbose()? Good point. I think not. So we can leave dump_page() with dump_page_owner() stuff and have __dump_page() or something as lighter version. -- Kirill A. Shutemov -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-04 16:10 +0100 |
| Subject | [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock |
| Message-ID | <qr7Rg-24F-19@gated-at.bofh.it> |
| In reply to | #1262329 |
The information in /sys/kernel/debug/page_owner includes the migratetype declared during the page allocation via gfp_flags. This is also checked against the pageblock's migratetype, and reported as Fallback allocation if these two differ (although in fact fallback allocation is not the only reason why they can differ). However, the migratetype actually printed is the one of the pageblock, not of the page itself, so it's the same for all pages in the pageblock. This is apparently a bug, noticed when working on other page_owner improvements. Fixed. Signed-off-by: Vlastimil Babka <vbabka@suse.cz> --- mm/page_owner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/page_owner.c b/mm/page_owner.c index 983c3a1..a9f16b8 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -113,7 +113,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn, "PFN %lu Block %lu type %d %s Flags %s%s%s%s%s%s%s%s%s%s%s%s\n", pfn, pfn >> pageblock_order, - pageblock_mt, + page_mt, pageblock_mt != page_mt ? "Fallback" : " ", PageLocked(page) ? "K" : " ", PageError(page) ? "E" : " ", -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <iamjoonsoo.kim@lge.com> |
|---|---|
| Date | 2015-11-05 09:10 +0100 |
| Subject | Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock |
| Message-ID | <qrnMm-3ZY-9@gated-at.bofh.it> |
| In reply to | #1262335 |
On Wed, Nov 04, 2015 at 04:00:57PM +0100, Vlastimil Babka wrote: > The information in /sys/kernel/debug/page_owner includes the migratetype > declared during the page allocation via gfp_flags. This is also checked against > the pageblock's migratetype, and reported as Fallback allocation if these two > differ (although in fact fallback allocation is not the only reason why they > can differ). > > However, the migratetype actually printed is the one of the pageblock, not of > the page itself, so it's the same for all pages in the pageblock. This is > apparently a bug, noticed when working on other page_owner improvements. Fixed. We can guess page migratetype through gfp_mask output although it isn't easy task for now. But, there is no way to know pageblock migratetype. I used this to know how memory is fragmented. Thanks. > > Signed-off-by: Vlastimil Babka <vbabka@suse.cz> > --- > mm/page_owner.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/mm/page_owner.c b/mm/page_owner.c > index 983c3a1..a9f16b8 100644 > --- a/mm/page_owner.c > +++ b/mm/page_owner.c > @@ -113,7 +113,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn, > "PFN %lu Block %lu type %d %s Flags %s%s%s%s%s%s%s%s%s%s%s%s\n", > pfn, > pfn >> pageblock_order, > - pageblock_mt, > + page_mt, > pageblock_mt != page_mt ? "Fallback" : " ", > PageLocked(page) ? "K" : " ", > PageError(page) ? "E" : " ", > -- > 2.6.2 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Joonsoo Kim <iamjoonsoo.kim@lge.com> |
|---|---|
| Date | 2015-11-05 09:20 +0100 |
| Subject | Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock |
| Message-ID | <qrnW2-44c-5@gated-at.bofh.it> |
| In reply to | #1262986 |
On Thu, Nov 05, 2015 at 09:15:01AM +0100, Vlastimil Babka wrote: > On 11/05/2015 09:09 AM, Joonsoo Kim wrote: > > On Wed, Nov 04, 2015 at 04:00:57PM +0100, Vlastimil Babka wrote: > >> The information in /sys/kernel/debug/page_owner includes the migratetype > >> declared during the page allocation via gfp_flags. This is also checked against > >> the pageblock's migratetype, and reported as Fallback allocation if these two > >> differ (although in fact fallback allocation is not the only reason why they > >> can differ). > >> > >> However, the migratetype actually printed is the one of the pageblock, not of > >> the page itself, so it's the same for all pages in the pageblock. This is > >> apparently a bug, noticed when working on other page_owner improvements. Fixed. > > > > We can guess page migratetype through gfp_mask output although it isn't > > easy task for now. But, there is no way to know pageblock migratetype. > > I used this to know how memory is fragmented. > > Ah, I see. How bout just we print both migratetypes then and remove the > "Fallback" part, which can be trivially deduced from them (and as I noted it's > somewhat misleading anyway)? I'm okay with your new suggestion. Thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-05 09:20 +0100 |
| Subject | Re: [PATCH 1/5] mm, page_owner: print migratetype of a page, not pageblock |
| Message-ID | <qrnW2-44c-7@gated-at.bofh.it> |
| In reply to | #1262986 |
On 11/05/2015 09:09 AM, Joonsoo Kim wrote: > On Wed, Nov 04, 2015 at 04:00:57PM +0100, Vlastimil Babka wrote: >> The information in /sys/kernel/debug/page_owner includes the migratetype >> declared during the page allocation via gfp_flags. This is also checked against >> the pageblock's migratetype, and reported as Fallback allocation if these two >> differ (although in fact fallback allocation is not the only reason why they >> can differ). >> >> However, the migratetype actually printed is the one of the pageblock, not of >> the page itself, so it's the same for all pages in the pageblock. This is >> apparently a bug, noticed when working on other page_owner improvements. Fixed. > > We can guess page migratetype through gfp_mask output although it isn't > easy task for now. But, there is no way to know pageblock migratetype. > I used this to know how memory is fragmented. Ah, I see. How bout just we print both migratetypes then and remove the "Fallback" part, which can be trivially deduced from them (and as I noted it's somewhat misleading anyway)? > Thanks. > >> >> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> >> --- >> mm/page_owner.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/mm/page_owner.c b/mm/page_owner.c >> index 983c3a1..a9f16b8 100644 >> --- a/mm/page_owner.c >> +++ b/mm/page_owner.c >> @@ -113,7 +113,7 @@ print_page_owner(char __user *buf, size_t count, unsigned long pfn, >> "PFN %lu Block %lu type %d %s Flags %s%s%s%s%s%s%s%s%s%s%s%s\n", >> pfn, >> pfn >> pageblock_order, >> - pageblock_mt, >> + page_mt, >> pageblock_mt != page_mt ? "Fallback" : " ", >> PageLocked(page) ? "K" : " ", >> PageError(page) ? "E" : " ", >> -- >> 2.6.2 >> >> -- >> To unsubscribe, send a message with 'unsubscribe linux-mm' in >> the body to majordomo@kvack.org. For more info on Linux MM, >> see: http://www.linux-mm.org/ . >> Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Vlastimil Babka <vbabka@suse.cz> |
|---|---|
| Date | 2015-11-04 16:10 +0100 |
| Subject | [PATCH 2/5] mm, page_owner: convert page_owner_inited to static key |
| Message-ID | <qr7Rg-24F-21@gated-at.bofh.it> |
| In reply to | #1262329 |
CONFIG_PAGE_OWNER attempts to impose negligible runtime overhead when enabled
during compilation, but not actually enabled during runtime by boot param
page_owner=on. This overhead can be further reduced using the static key
mechanism, which this patch does.
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
---
Documentation/vm/page_owner.txt | 9 +++++----
include/linux/page_owner.h | 22 ++++++++++------------
mm/page_owner.c | 9 +++++----
mm/vmstat.c | 2 +-
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/Documentation/vm/page_owner.txt b/Documentation/vm/page_owner.txt
index 8f3ce9b..ffff143 100644
--- a/Documentation/vm/page_owner.txt
+++ b/Documentation/vm/page_owner.txt
@@ -28,10 +28,11 @@ with page owner and page owner is disabled in runtime due to no enabling
boot option, runtime overhead is marginal. If disabled in runtime, it
doesn't require memory to store owner information, so there is no runtime
memory overhead. And, page owner inserts just two unlikely branches into
-the page allocator hotpath and if it returns false then allocation is
-done like as the kernel without page owner. These two unlikely branches
-would not affect to allocation performance. Following is the kernel's
-code size change due to this facility.
+the page allocator hotpath and if not enabled, then allocation is done
+like as the kernel without page owner. These two unlikely branches should
+not affect to allocation performance, especially if the static keys jump
+label patching functionality is available. Following is the kernel's code
+size change due to this facility.
- Without page owner
text data bss dec hex filename
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index cacaabe..8e2eb15 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -1,8 +1,10 @@
#ifndef __LINUX_PAGE_OWNER_H
#define __LINUX_PAGE_OWNER_H
+#include <linux/jump_label.h>
+
#ifdef CONFIG_PAGE_OWNER
-extern bool page_owner_inited;
+extern struct static_key_false page_owner_inited;
extern struct page_ext_operations page_owner_ops;
extern void __reset_page_owner(struct page *page, unsigned int order);
@@ -12,27 +14,23 @@ extern gfp_t __get_page_owner_gfp(struct page *page);
static inline void reset_page_owner(struct page *page, unsigned int order)
{
- if (likely(!page_owner_inited))
- return;
-
- __reset_page_owner(page, order);
+ if (static_branch_unlikely(&page_owner_inited))
+ __reset_page_owner(page, order);
}
static inline void set_page_owner(struct page *page,
unsigned int order, gfp_t gfp_mask)
{
- if (likely(!page_owner_inited))
- return;
-
- __set_page_owner(page, order, gfp_mask);
+ if (static_branch_unlikely(&page_owner_inited))
+ __set_page_owner(page, order, gfp_mask);
}
static inline gfp_t get_page_owner_gfp(struct page *page)
{
- if (likely(!page_owner_inited))
+ if (static_branch_unlikely(&page_owner_inited))
+ return __get_page_owner_gfp(page);
+ else
return 0;
-
- return __get_page_owner_gfp(page);
}
#else
static inline void reset_page_owner(struct page *page, unsigned int order)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index a9f16b8..7664b85 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -5,10 +5,11 @@
#include <linux/bootmem.h>
#include <linux/stacktrace.h>
#include <linux/page_owner.h>
+#include <linux/jump_label.h>
#include "internal.h"
static bool page_owner_disabled = true;
-bool page_owner_inited __read_mostly;
+DEFINE_STATIC_KEY_FALSE(page_owner_inited);
static void init_early_allocated_pages(void);
@@ -37,7 +38,7 @@ static void init_page_owner(void)
if (page_owner_disabled)
return;
- page_owner_inited = true;
+ static_branch_enable(&page_owner_inited);
init_early_allocated_pages();
}
@@ -157,7 +158,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
struct page *page;
struct page_ext *page_ext;
- if (!page_owner_inited)
+ if (!static_branch_unlikely(&page_owner_inited))
return -EINVAL;
page = NULL;
@@ -305,7 +306,7 @@ static int __init pageowner_init(void)
{
struct dentry *dentry;
- if (!page_owner_inited) {
+ if (!static_branch_unlikely(&page_owner_inited)) {
pr_info("page_owner is disabled\n");
return 0;
}
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 34f480b..d9be9ab 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1131,7 +1131,7 @@ static void pagetypeinfo_showmixedcount(struct seq_file *m, pg_data_t *pgdat)
#ifdef CONFIG_PAGE_OWNER
int mtype;
- if (!page_owner_inited)
+ if (!static_branch_unlikely(&page_owner_inited))
return;
drain_all_pages(NULL);
--
2.6.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web