Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Vlastimil Babka and committed by
Linus Torvalds
7dd80b8a 60f30350

+21 -21
+5 -4
Documentation/vm/page_owner.txt
··· 28 28 boot option, runtime overhead is marginal. If disabled in runtime, it 29 29 doesn't require memory to store owner information, so there is no runtime 30 30 memory overhead. And, page owner inserts just two unlikely branches into 31 - the page allocator hotpath and if it returns false then allocation is 32 - done like as the kernel without page owner. These two unlikely branches 33 - would not affect to allocation performance. Following is the kernel's 34 - code size change due to this facility. 31 + the page allocator hotpath and if not enabled, then allocation is done 32 + like as the kernel without page owner. These two unlikely branches should 33 + not affect to allocation performance, especially if the static keys jump 34 + label patching functionality is available. Following is the kernel's code 35 + size change due to this facility. 35 36 36 37 - Without page owner 37 38 text data bss dec hex filename
+10 -12
include/linux/page_owner.h
··· 1 1 #ifndef __LINUX_PAGE_OWNER_H 2 2 #define __LINUX_PAGE_OWNER_H 3 3 4 + #include <linux/jump_label.h> 5 + 4 6 #ifdef CONFIG_PAGE_OWNER 5 - extern bool page_owner_inited; 7 + extern struct static_key_false page_owner_inited; 6 8 extern struct page_ext_operations page_owner_ops; 7 9 8 10 extern void __reset_page_owner(struct page *page, unsigned int order); ··· 14 12 15 13 static inline void reset_page_owner(struct page *page, unsigned int order) 16 14 { 17 - if (likely(!page_owner_inited)) 18 - return; 19 - 20 - __reset_page_owner(page, order); 15 + if (static_branch_unlikely(&page_owner_inited)) 16 + __reset_page_owner(page, order); 21 17 } 22 18 23 19 static inline void set_page_owner(struct page *page, 24 20 unsigned int order, gfp_t gfp_mask) 25 21 { 26 - if (likely(!page_owner_inited)) 27 - return; 28 - 29 - __set_page_owner(page, order, gfp_mask); 22 + if (static_branch_unlikely(&page_owner_inited)) 23 + __set_page_owner(page, order, gfp_mask); 30 24 } 31 25 32 26 static inline gfp_t get_page_owner_gfp(struct page *page) 33 27 { 34 - if (likely(!page_owner_inited)) 28 + if (static_branch_unlikely(&page_owner_inited)) 29 + return __get_page_owner_gfp(page); 30 + else 35 31 return 0; 36 - 37 - return __get_page_owner_gfp(page); 38 32 } 39 33 #else 40 34 static inline void reset_page_owner(struct page *page, unsigned int order)
+5 -4
mm/page_owner.c
··· 5 5 #include <linux/bootmem.h> 6 6 #include <linux/stacktrace.h> 7 7 #include <linux/page_owner.h> 8 + #include <linux/jump_label.h> 8 9 #include "internal.h" 9 10 10 11 static bool page_owner_disabled = true; 11 - bool page_owner_inited __read_mostly; 12 + DEFINE_STATIC_KEY_FALSE(page_owner_inited); 12 13 13 14 static void init_early_allocated_pages(void); 14 15 ··· 38 37 if (page_owner_disabled) 39 38 return; 40 39 41 - page_owner_inited = true; 40 + static_branch_enable(&page_owner_inited); 42 41 init_early_allocated_pages(); 43 42 } 44 43 ··· 148 147 struct page *page; 149 148 struct page_ext *page_ext; 150 149 151 - if (!page_owner_inited) 150 + if (!static_branch_unlikely(&page_owner_inited)) 152 151 return -EINVAL; 153 152 154 153 page = NULL; ··· 296 295 { 297 296 struct dentry *dentry; 298 297 299 - if (!page_owner_inited) { 298 + if (!static_branch_unlikely(&page_owner_inited)) { 300 299 pr_info("page_owner is disabled\n"); 301 300 return 0; 302 301 }
+1 -1
mm/vmstat.c
··· 1120 1120 #ifdef CONFIG_PAGE_OWNER 1121 1121 int mtype; 1122 1122 1123 - if (!page_owner_inited) 1123 + if (!static_branch_unlikely(&page_owner_inited)) 1124 1124 return; 1125 1125 1126 1126 drain_all_pages(NULL);