diff options
Diffstat (limited to 'mm/huge_memory.c')
-rw-r--r-- | mm/huge_memory.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 5f902e20e8c0..04eb489a6805 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c | |||
@@ -47,6 +47,7 @@ static unsigned int khugepaged_scan_sleep_millisecs __read_mostly = 10000; | |||
47 | /* during fragmentation poll the hugepage allocator once every minute */ | 47 | /* during fragmentation poll the hugepage allocator once every minute */ |
48 | static unsigned int khugepaged_alloc_sleep_millisecs __read_mostly = 60000; | 48 | static unsigned int khugepaged_alloc_sleep_millisecs __read_mostly = 60000; |
49 | static struct task_struct *khugepaged_thread __read_mostly; | 49 | static struct task_struct *khugepaged_thread __read_mostly; |
50 | static unsigned long huge_zero_pfn __read_mostly; | ||
50 | static DEFINE_MUTEX(khugepaged_mutex); | 51 | static DEFINE_MUTEX(khugepaged_mutex); |
51 | static DEFINE_SPINLOCK(khugepaged_mm_lock); | 52 | static DEFINE_SPINLOCK(khugepaged_mm_lock); |
52 | static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait); | 53 | static DECLARE_WAIT_QUEUE_HEAD(khugepaged_wait); |
@@ -159,6 +160,29 @@ static int start_khugepaged(void) | |||
159 | return err; | 160 | return err; |
160 | } | 161 | } |
161 | 162 | ||
163 | static int __init init_huge_zero_page(void) | ||
164 | { | ||
165 | struct page *hpage; | ||
166 | |||
167 | hpage = alloc_pages((GFP_TRANSHUGE | __GFP_ZERO) & ~__GFP_MOVABLE, | ||
168 | HPAGE_PMD_ORDER); | ||
169 | if (!hpage) | ||
170 | return -ENOMEM; | ||
171 | |||
172 | huge_zero_pfn = page_to_pfn(hpage); | ||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static inline bool is_huge_zero_pfn(unsigned long pfn) | ||
177 | { | ||
178 | return pfn == huge_zero_pfn; | ||
179 | } | ||
180 | |||
181 | static inline bool is_huge_zero_pmd(pmd_t pmd) | ||
182 | { | ||
183 | return is_huge_zero_pfn(pmd_pfn(pmd)); | ||
184 | } | ||
185 | |||
162 | #ifdef CONFIG_SYSFS | 186 | #ifdef CONFIG_SYSFS |
163 | 187 | ||
164 | static ssize_t double_flag_show(struct kobject *kobj, | 188 | static ssize_t double_flag_show(struct kobject *kobj, |
@@ -540,6 +564,10 @@ static int __init hugepage_init(void) | |||
540 | if (err) | 564 | if (err) |
541 | return err; | 565 | return err; |
542 | 566 | ||
567 | err = init_huge_zero_page(); | ||
568 | if (err) | ||
569 | goto out; | ||
570 | |||
543 | err = khugepaged_slab_init(); | 571 | err = khugepaged_slab_init(); |
544 | if (err) | 572 | if (err) |
545 | goto out; | 573 | goto out; |
@@ -562,6 +590,8 @@ static int __init hugepage_init(void) | |||
562 | 590 | ||
563 | return 0; | 591 | return 0; |
564 | out: | 592 | out: |
593 | if (huge_zero_pfn) | ||
594 | __free_page(pfn_to_page(huge_zero_pfn)); | ||
565 | hugepage_exit_sysfs(hugepage_kobj); | 595 | hugepage_exit_sysfs(hugepage_kobj); |
566 | return err; | 596 | return err; |
567 | } | 597 | } |