aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2016-03-15 17:56:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-15 19:55:16 -0400
commit7dd80b8af0bcd705a9ef2fa272c082882616a499 (patch)
tree75048a0e7ff2648c59b1a23640e202653fa1aa27
parent60f30350fd69a3e4d5f0f45937d3274c22565134 (diff)
mm, page_owner: convert page_owner_inited to static key
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> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Sasha Levin <sasha.levin@oracle.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Cc: Mel Gorman <mgorman@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/vm/page_owner.txt9
-rw-r--r--include/linux/page_owner.h22
-rw-r--r--mm/page_owner.c9
-rw-r--r--mm/vmstat.c2
4 files changed, 21 insertions, 21 deletions
diff --git a/Documentation/vm/page_owner.txt b/Documentation/vm/page_owner.txt
index 8f3ce9b3aa11..ffff1439076a 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
28boot option, runtime overhead is marginal. If disabled in runtime, it 28boot option, runtime overhead is marginal. If disabled in runtime, it
29doesn't require memory to store owner information, so there is no runtime 29doesn't require memory to store owner information, so there is no runtime
30memory overhead. And, page owner inserts just two unlikely branches into 30memory overhead. And, page owner inserts just two unlikely branches into
31the page allocator hotpath and if it returns false then allocation is 31the page allocator hotpath and if not enabled, then allocation is done
32done like as the kernel without page owner. These two unlikely branches 32like as the kernel without page owner. These two unlikely branches should
33would not affect to allocation performance. Following is the kernel's 33not affect to allocation performance, especially if the static keys jump
34code size change due to this facility. 34label patching functionality is available. Following is the kernel's code
35size change due to this facility.
35 36
36- Without page owner 37- Without page owner
37 text data bss dec hex filename 38 text data bss dec hex filename
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index cacaabea8a09..8e2eb153c7b9 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -1,8 +1,10 @@
1#ifndef __LINUX_PAGE_OWNER_H 1#ifndef __LINUX_PAGE_OWNER_H
2#define __LINUX_PAGE_OWNER_H 2#define __LINUX_PAGE_OWNER_H
3 3
4#include <linux/jump_label.h>
5
4#ifdef CONFIG_PAGE_OWNER 6#ifdef CONFIG_PAGE_OWNER
5extern bool page_owner_inited; 7extern struct static_key_false page_owner_inited;
6extern struct page_ext_operations page_owner_ops; 8extern struct page_ext_operations page_owner_ops;
7 9
8extern void __reset_page_owner(struct page *page, unsigned int order); 10extern void __reset_page_owner(struct page *page, unsigned int order);
@@ -12,27 +14,23 @@ extern gfp_t __get_page_owner_gfp(struct page *page);
12 14
13static inline void reset_page_owner(struct page *page, unsigned int order) 15static inline void reset_page_owner(struct page *page, unsigned int order)
14{ 16{
15 if (likely(!page_owner_inited)) 17 if (static_branch_unlikely(&page_owner_inited))
16 return; 18 __reset_page_owner(page, order);
17
18 __reset_page_owner(page, order);
19} 19}
20 20
21static inline void set_page_owner(struct page *page, 21static inline void set_page_owner(struct page *page,
22 unsigned int order, gfp_t gfp_mask) 22 unsigned int order, gfp_t gfp_mask)
23{ 23{
24 if (likely(!page_owner_inited)) 24 if (static_branch_unlikely(&page_owner_inited))
25 return; 25 __set_page_owner(page, order, gfp_mask);
26
27 __set_page_owner(page, order, gfp_mask);
28} 26}
29 27
30static inline gfp_t get_page_owner_gfp(struct page *page) 28static inline gfp_t get_page_owner_gfp(struct page *page)
31{ 29{
32 if (likely(!page_owner_inited)) 30 if (static_branch_unlikely(&page_owner_inited))
31 return __get_page_owner_gfp(page);
32 else
33 return 0; 33 return 0;
34
35 return __get_page_owner_gfp(page);
36} 34}
37#else 35#else
38static inline void reset_page_owner(struct page *page, unsigned int order) 36static inline void reset_page_owner(struct page *page, unsigned int order)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 7a37a30d941b..feaa28b40c1c 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -5,10 +5,11 @@
5#include <linux/bootmem.h> 5#include <linux/bootmem.h>
6#include <linux/stacktrace.h> 6#include <linux/stacktrace.h>
7#include <linux/page_owner.h> 7#include <linux/page_owner.h>
8#include <linux/jump_label.h>
8#include "internal.h" 9#include "internal.h"
9 10
10static bool page_owner_disabled = true; 11static bool page_owner_disabled = true;
11bool page_owner_inited __read_mostly; 12DEFINE_STATIC_KEY_FALSE(page_owner_inited);
12 13
13static void init_early_allocated_pages(void); 14static void init_early_allocated_pages(void);
14 15
@@ -37,7 +38,7 @@ static void init_page_owner(void)
37 if (page_owner_disabled) 38 if (page_owner_disabled)
38 return; 39 return;
39 40
40 page_owner_inited = true; 41 static_branch_enable(&page_owner_inited);
41 init_early_allocated_pages(); 42 init_early_allocated_pages();
42} 43}
43 44
@@ -147,7 +148,7 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos)
147 struct page *page; 148 struct page *page;
148 struct page_ext *page_ext; 149 struct page_ext *page_ext;
149 150
150 if (!page_owner_inited) 151 if (!static_branch_unlikely(&page_owner_inited))
151 return -EINVAL; 152 return -EINVAL;
152 153
153 page = NULL; 154 page = NULL;
@@ -295,7 +296,7 @@ static int __init pageowner_init(void)
295{ 296{
296 struct dentry *dentry; 297 struct dentry *dentry;
297 298
298 if (!page_owner_inited) { 299 if (!static_branch_unlikely(&page_owner_inited)) {
299 pr_info("page_owner is disabled\n"); 300 pr_info("page_owner is disabled\n");
300 return 0; 301 return 0;
301 } 302 }
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 72c17981cb70..69ce64f7b8d7 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1120,7 +1120,7 @@ static void pagetypeinfo_showmixedcount(struct seq_file *m, pg_data_t *pgdat)
1120#ifdef CONFIG_PAGE_OWNER 1120#ifdef CONFIG_PAGE_OWNER
1121 int mtype; 1121 int mtype;
1122 1122
1123 if (!page_owner_inited) 1123 if (!static_branch_unlikely(&page_owner_inited))
1124 return; 1124 return;
1125 1125
1126 drain_all_pages(NULL); 1126 drain_all_pages(NULL);