summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/arm64/include/asm/hugetlb.h4
-rw-r--r--arch/powerpc/include/asm/book3s/64/hugetlb.h5
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype2
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/s390/include/asm/hugetlb.h8
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/hugetlb.h4
-rw-r--r--include/asm-generic/hugetlb.h7
-rw-r--r--include/linux/gfp.h2
-rw-r--r--mm/hugetlb.c54
-rw-r--r--mm/page_alloc.c4
14 files changed, 61 insertions, 39 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 7f7fbd8bd9d5..7a1aa53d188d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -19,7 +19,7 @@ config ARM64
19 select ARCH_HAS_FAST_MULTIPLIER 19 select ARCH_HAS_FAST_MULTIPLIER
20 select ARCH_HAS_FORTIFY_SOURCE 20 select ARCH_HAS_FORTIFY_SOURCE
21 select ARCH_HAS_GCOV_PROFILE_ALL 21 select ARCH_HAS_GCOV_PROFILE_ALL
22 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 22 select ARCH_HAS_GIGANTIC_PAGE
23 select ARCH_HAS_KCOV 23 select ARCH_HAS_KCOV
24 select ARCH_HAS_KEEPINITRD 24 select ARCH_HAS_KEEPINITRD
25 select ARCH_HAS_MEMBARRIER_SYNC_CORE 25 select ARCH_HAS_MEMBARRIER_SYNC_CORE
diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hugetlb.h
index c6a07a3b433e..4aad6382f631 100644
--- a/arch/arm64/include/asm/hugetlb.h
+++ b/arch/arm64/include/asm/hugetlb.h
@@ -70,8 +70,4 @@ extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
70 70
71#include <asm-generic/hugetlb.h> 71#include <asm-generic/hugetlb.h>
72 72
73#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
74static inline bool gigantic_page_supported(void) { return true; }
75#endif
76
77#endif /* __ASM_HUGETLB_H */ 73#endif /* __ASM_HUGETLB_H */
diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 56140d19c85f..12e150e615b7 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -36,8 +36,8 @@ static inline int hstate_get_psize(struct hstate *hstate)
36 } 36 }
37} 37}
38 38
39#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE 39#define __HAVE_ARCH_GIGANTIC_PAGE_RUNTIME_SUPPORTED
40static inline bool gigantic_page_supported(void) 40static inline bool gigantic_page_runtime_supported(void)
41{ 41{
42 /* 42 /*
43 * We used gigantic page reservation with hypervisor assist in some case. 43 * We used gigantic page reservation with hypervisor assist in some case.
@@ -49,7 +49,6 @@ static inline bool gigantic_page_supported(void)
49 49
50 return true; 50 return true;
51} 51}
52#endif
53 52
54/* hugepd entry valid bit */ 53/* hugepd entry valid bit */
55#define HUGEPD_VAL_BITS (0x8000000000000000UL) 54#define HUGEPD_VAL_BITS (0x8000000000000000UL)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 3a31d4289ea4..2794235e9d3e 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -331,7 +331,7 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK
331config PPC_RADIX_MMU 331config PPC_RADIX_MMU
332 bool "Radix MMU Support" 332 bool "Radix MMU Support"
333 depends on PPC_BOOK3S_64 && HUGETLB_PAGE 333 depends on PPC_BOOK3S_64 && HUGETLB_PAGE
334 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 334 select ARCH_HAS_GIGANTIC_PAGE
335 select PPC_HAVE_KUEP 335 select PPC_HAVE_KUEP
336 select PPC_HAVE_KUAP 336 select PPC_HAVE_KUAP
337 default y 337 default y
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 724dbc6b7d33..d0c046af65fa 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -63,7 +63,7 @@ config S390
63 select ARCH_HAS_ELF_RANDOMIZE 63 select ARCH_HAS_ELF_RANDOMIZE
64 select ARCH_HAS_FORTIFY_SOURCE 64 select ARCH_HAS_FORTIFY_SOURCE
65 select ARCH_HAS_GCOV_PROFILE_ALL 65 select ARCH_HAS_GCOV_PROFILE_ALL
66 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 66 select ARCH_HAS_GIGANTIC_PAGE
67 select ARCH_HAS_KCOV 67 select ARCH_HAS_KCOV
68 select ARCH_HAS_PTE_SPECIAL 68 select ARCH_HAS_PTE_SPECIAL
69 select ARCH_HAS_SET_MEMORY 69 select ARCH_HAS_SET_MEMORY
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 2d1afa58a4b6..bb59dd964590 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -116,7 +116,9 @@ static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
116 return pte_modify(pte, newprot); 116 return pte_modify(pte, newprot);
117} 117}
118 118
119#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE 119static inline bool gigantic_page_runtime_supported(void)
120static inline bool gigantic_page_supported(void) { return true; } 120{
121#endif 121 return true;
122}
123
122#endif /* _ASM_S390_HUGETLB_H */ 124#endif /* _ASM_S390_HUGETLB_H */
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 2a5ec643fec0..2a77033e1e7c 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -53,7 +53,7 @@ config SUPERH
53 select HAVE_FUTEX_CMPXCHG if FUTEX 53 select HAVE_FUTEX_CMPXCHG if FUTEX
54 select HAVE_NMI 54 select HAVE_NMI
55 select NEED_SG_DMA_LENGTH 55 select NEED_SG_DMA_LENGTH
56 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 56 select ARCH_HAS_GIGANTIC_PAGE
57 57
58 help 58 help
59 The SuperH is a RISC processor targeted for use in embedded systems 59 The SuperH is a RISC processor targeted for use in embedded systems
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 566de738e487..7c93f3121ee6 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -92,7 +92,7 @@ config SPARC64
92 select ARCH_CLOCKSOURCE_DATA 92 select ARCH_CLOCKSOURCE_DATA
93 select ARCH_HAS_PTE_SPECIAL 93 select ARCH_HAS_PTE_SPECIAL
94 select PCI_DOMAINS if PCI 94 select PCI_DOMAINS if PCI
95 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 95 select ARCH_HAS_GIGANTIC_PAGE
96 96
97config ARCH_DEFCONFIG 97config ARCH_DEFCONFIG
98 string 98 string
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 526d95abfe5e..f21bc56e5d7b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -22,7 +22,7 @@ config X86_64
22 def_bool y 22 def_bool y
23 depends on 64BIT 23 depends on 64BIT
24 # Options that are inherently 64-bit kernel only: 24 # Options that are inherently 64-bit kernel only:
25 select ARCH_HAS_GIGANTIC_PAGE if CONTIG_ALLOC 25 select ARCH_HAS_GIGANTIC_PAGE
26 select ARCH_SUPPORTS_INT128 26 select ARCH_SUPPORTS_INT128
27 select ARCH_USE_CMPXCHG_LOCKREF 27 select ARCH_USE_CMPXCHG_LOCKREF
28 select HAVE_ARCH_SOFT_DIRTY 28 select HAVE_ARCH_SOFT_DIRTY
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
index 7469d321f072..f65cfb48cfdd 100644
--- a/arch/x86/include/asm/hugetlb.h
+++ b/arch/x86/include/asm/hugetlb.h
@@ -17,8 +17,4 @@ static inline void arch_clear_hugepage_flags(struct page *page)
17{ 17{
18} 18}
19 19
20#ifdef CONFIG_ARCH_HAS_GIGANTIC_PAGE
21static inline bool gigantic_page_supported(void) { return true; }
22#endif
23
24#endif /* _ASM_X86_HUGETLB_H */ 20#endif /* _ASM_X86_HUGETLB_H */
diff --git a/include/asm-generic/hugetlb.h b/include/asm-generic/hugetlb.h
index 71d7b77eea50..822f433ac95c 100644
--- a/include/asm-generic/hugetlb.h
+++ b/include/asm-generic/hugetlb.h
@@ -126,4 +126,11 @@ static inline pte_t huge_ptep_get(pte_t *ptep)
126} 126}
127#endif 127#endif
128 128
129#ifndef __HAVE_ARCH_GIGANTIC_PAGE_RUNTIME_SUPPORTED
130static inline bool gigantic_page_runtime_supported(void)
131{
132 return IS_ENABLED(CONFIG_ARCH_HAS_GIGANTIC_PAGE);
133}
134#endif /* __HAVE_ARCH_GIGANTIC_PAGE_RUNTIME_SUPPORTED */
135
129#endif /* _ASM_GENERIC_HUGETLB_H */ 136#endif /* _ASM_GENERIC_HUGETLB_H */
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index e77ab30e9328..fb07b503dc45 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -589,8 +589,8 @@ static inline bool pm_suspended_storage(void)
589/* The below functions must be run on a range from a single zone. */ 589/* The below functions must be run on a range from a single zone. */
590extern int alloc_contig_range(unsigned long start, unsigned long end, 590extern int alloc_contig_range(unsigned long start, unsigned long end,
591 unsigned migratetype, gfp_t gfp_mask); 591 unsigned migratetype, gfp_t gfp_mask);
592extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
593#endif 592#endif
593void free_contig_range(unsigned long pfn, unsigned int nr_pages);
594 594
595#ifdef CONFIG_CMA 595#ifdef CONFIG_CMA
596/* CMA stuff */ 596/* CMA stuff */
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index dffe5d9d03ae..2f901a6e13d2 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1059,6 +1059,7 @@ static void free_gigantic_page(struct page *page, unsigned int order)
1059 free_contig_range(page_to_pfn(page), 1 << order); 1059 free_contig_range(page_to_pfn(page), 1 << order);
1060} 1060}
1061 1061
1062#ifdef CONFIG_CONTIG_ALLOC
1062static int __alloc_gigantic_page(unsigned long start_pfn, 1063static int __alloc_gigantic_page(unsigned long start_pfn,
1063 unsigned long nr_pages, gfp_t gfp_mask) 1064 unsigned long nr_pages, gfp_t gfp_mask)
1064{ 1065{
@@ -1143,11 +1144,20 @@ static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
1143 1144
1144static void prep_new_huge_page(struct hstate *h, struct page *page, int nid); 1145static void prep_new_huge_page(struct hstate *h, struct page *page, int nid);
1145static void prep_compound_gigantic_page(struct page *page, unsigned int order); 1146static void prep_compound_gigantic_page(struct page *page, unsigned int order);
1147#else /* !CONFIG_CONTIG_ALLOC */
1148static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
1149 int nid, nodemask_t *nodemask)
1150{
1151 return NULL;
1152}
1153#endif /* CONFIG_CONTIG_ALLOC */
1146 1154
1147#else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE */ 1155#else /* !CONFIG_ARCH_HAS_GIGANTIC_PAGE */
1148static inline bool gigantic_page_supported(void) { return false; }
1149static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, 1156static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask,
1150 int nid, nodemask_t *nodemask) { return NULL; } 1157 int nid, nodemask_t *nodemask)
1158{
1159 return NULL;
1160}
1151static inline void free_gigantic_page(struct page *page, unsigned int order) { } 1161static inline void free_gigantic_page(struct page *page, unsigned int order) { }
1152static inline void destroy_compound_gigantic_page(struct page *page, 1162static inline void destroy_compound_gigantic_page(struct page *page,
1153 unsigned int order) { } 1163 unsigned int order) { }
@@ -1157,7 +1167,7 @@ static void update_and_free_page(struct hstate *h, struct page *page)
1157{ 1167{
1158 int i; 1168 int i;
1159 1169
1160 if (hstate_is_gigantic(h) && !gigantic_page_supported()) 1170 if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
1161 return; 1171 return;
1162 1172
1163 h->nr_huge_pages--; 1173 h->nr_huge_pages--;
@@ -2278,13 +2288,27 @@ found:
2278} 2288}
2279 2289
2280#define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages) 2290#define persistent_huge_pages(h) (h->nr_huge_pages - h->surplus_huge_pages)
2281static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, 2291static int set_max_huge_pages(struct hstate *h, unsigned long count,
2282 nodemask_t *nodes_allowed) 2292 nodemask_t *nodes_allowed)
2283{ 2293{
2284 unsigned long min_count, ret; 2294 unsigned long min_count, ret;
2285 2295
2286 if (hstate_is_gigantic(h) && !gigantic_page_supported()) 2296 spin_lock(&hugetlb_lock);
2287 return h->max_huge_pages; 2297
2298 /*
2299 * Gigantic pages runtime allocation depend on the capability for large
2300 * page range allocation.
2301 * If the system does not provide this feature, return an error when
2302 * the user tries to allocate gigantic pages but let the user free the
2303 * boottime allocated gigantic pages.
2304 */
2305 if (hstate_is_gigantic(h) && !IS_ENABLED(CONFIG_CONTIG_ALLOC)) {
2306 if (count > persistent_huge_pages(h)) {
2307 spin_unlock(&hugetlb_lock);
2308 return -EINVAL;
2309 }
2310 /* Fall through to decrease pool */
2311 }
2288 2312
2289 /* 2313 /*
2290 * Increase the pool size 2314 * Increase the pool size
@@ -2297,7 +2321,6 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
2297 * pool might be one hugepage larger than it needs to be, but 2321 * pool might be one hugepage larger than it needs to be, but
2298 * within all the constraints specified by the sysctls. 2322 * within all the constraints specified by the sysctls.
2299 */ 2323 */
2300 spin_lock(&hugetlb_lock);
2301 while (h->surplus_huge_pages && count > persistent_huge_pages(h)) { 2324 while (h->surplus_huge_pages && count > persistent_huge_pages(h)) {
2302 if (!adjust_pool_surplus(h, nodes_allowed, -1)) 2325 if (!adjust_pool_surplus(h, nodes_allowed, -1))
2303 break; 2326 break;
@@ -2352,9 +2375,10 @@ static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count,
2352 break; 2375 break;
2353 } 2376 }
2354out: 2377out:
2355 ret = persistent_huge_pages(h); 2378 h->max_huge_pages = persistent_huge_pages(h);
2356 spin_unlock(&hugetlb_lock); 2379 spin_unlock(&hugetlb_lock);
2357 return ret; 2380
2381 return 0;
2358} 2382}
2359 2383
2360#define HSTATE_ATTR_RO(_name) \ 2384#define HSTATE_ATTR_RO(_name) \
@@ -2406,7 +2430,7 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
2406 int err; 2430 int err;
2407 NODEMASK_ALLOC(nodemask_t, nodes_allowed, GFP_KERNEL | __GFP_NORETRY); 2431 NODEMASK_ALLOC(nodemask_t, nodes_allowed, GFP_KERNEL | __GFP_NORETRY);
2408 2432
2409 if (hstate_is_gigantic(h) && !gigantic_page_supported()) { 2433 if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported()) {
2410 err = -EINVAL; 2434 err = -EINVAL;
2411 goto out; 2435 goto out;
2412 } 2436 }
@@ -2430,15 +2454,13 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
2430 } else 2454 } else
2431 nodes_allowed = &node_states[N_MEMORY]; 2455 nodes_allowed = &node_states[N_MEMORY];
2432 2456
2433 h->max_huge_pages = set_max_huge_pages(h, count, nodes_allowed); 2457 err = set_max_huge_pages(h, count, nodes_allowed);
2434 2458
2459out:
2435 if (nodes_allowed != &node_states[N_MEMORY]) 2460 if (nodes_allowed != &node_states[N_MEMORY])
2436 NODEMASK_FREE(nodes_allowed); 2461 NODEMASK_FREE(nodes_allowed);
2437 2462
2438 return len; 2463 return err ? err : len;
2439out:
2440 NODEMASK_FREE(nodes_allowed);
2441 return err;
2442} 2464}
2443 2465
2444static ssize_t nr_hugepages_store_common(bool obey_mempolicy, 2466static ssize_t nr_hugepages_store_common(bool obey_mempolicy,
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2efb6525d932..4ea71bc70413 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -8346,8 +8346,9 @@ done:
8346 pfn_max_align_up(end), migratetype); 8346 pfn_max_align_up(end), migratetype);
8347 return ret; 8347 return ret;
8348} 8348}
8349#endif /* CONFIG_CONTIG_ALLOC */
8349 8350
8350void free_contig_range(unsigned long pfn, unsigned nr_pages) 8351void free_contig_range(unsigned long pfn, unsigned int nr_pages)
8351{ 8352{
8352 unsigned int count = 0; 8353 unsigned int count = 0;
8353 8354
@@ -8359,7 +8360,6 @@ void free_contig_range(unsigned long pfn, unsigned nr_pages)
8359 } 8360 }
8360 WARN(count != 0, "%d pages are still in use!\n", count); 8361 WARN(count != 0, "%d pages are still in use!\n", count);
8361} 8362}
8362#endif
8363 8363
8364#ifdef CONFIG_MEMORY_HOTPLUG 8364#ifdef CONFIG_MEMORY_HOTPLUG
8365/* 8365/*