diff options
-rw-r--r-- | arch/arm64/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/hugetlb.h | 4 | ||||
-rw-r--r-- | arch/powerpc/include/asm/book3s/64/hugetlb.h | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/Kconfig.cputype | 2 | ||||
-rw-r--r-- | arch/s390/Kconfig | 2 | ||||
-rw-r--r-- | arch/s390/include/asm/hugetlb.h | 8 | ||||
-rw-r--r-- | arch/sh/Kconfig | 2 | ||||
-rw-r--r-- | arch/sparc/Kconfig | 2 | ||||
-rw-r--r-- | arch/x86/Kconfig | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/hugetlb.h | 4 | ||||
-rw-r--r-- | include/asm-generic/hugetlb.h | 7 | ||||
-rw-r--r-- | include/linux/gfp.h | 2 | ||||
-rw-r--r-- | mm/hugetlb.c | 54 | ||||
-rw-r--r-- | mm/page_alloc.c | 4 |
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 | ||
74 | static 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 |
40 | static inline bool gigantic_page_supported(void) | 40 | static 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 | |||
331 | config PPC_RADIX_MMU | 331 | config 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 | 119 | static inline bool gigantic_page_runtime_supported(void) |
120 | static 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 | ||
97 | config ARCH_DEFCONFIG | 97 | config 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 | ||
21 | static 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 | ||
130 | static 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. */ |
590 | extern int alloc_contig_range(unsigned long start, unsigned long end, | 590 | extern int alloc_contig_range(unsigned long start, unsigned long end, |
591 | unsigned migratetype, gfp_t gfp_mask); | 591 | unsigned migratetype, gfp_t gfp_mask); |
592 | extern void free_contig_range(unsigned long pfn, unsigned nr_pages); | ||
593 | #endif | 592 | #endif |
593 | void 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 | ||
1062 | static int __alloc_gigantic_page(unsigned long start_pfn, | 1063 | static 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 | ||
1144 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid); | 1145 | static void prep_new_huge_page(struct hstate *h, struct page *page, int nid); |
1145 | static void prep_compound_gigantic_page(struct page *page, unsigned int order); | 1146 | static void prep_compound_gigantic_page(struct page *page, unsigned int order); |
1147 | #else /* !CONFIG_CONTIG_ALLOC */ | ||
1148 | static 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 */ |
1148 | static inline bool gigantic_page_supported(void) { return false; } | ||
1149 | static struct page *alloc_gigantic_page(struct hstate *h, gfp_t gfp_mask, | 1156 | static 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 | } | ||
1151 | static inline void free_gigantic_page(struct page *page, unsigned int order) { } | 1161 | static inline void free_gigantic_page(struct page *page, unsigned int order) { } |
1152 | static inline void destroy_compound_gigantic_page(struct page *page, | 1162 | static 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) |
2281 | static unsigned long set_max_huge_pages(struct hstate *h, unsigned long count, | 2291 | static 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 | } |
2354 | out: | 2377 | out: |
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 | ||
2459 | out: | ||
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; |
2439 | out: | ||
2440 | NODEMASK_FREE(nodes_allowed); | ||
2441 | return err; | ||
2442 | } | 2464 | } |
2443 | 2465 | ||
2444 | static ssize_t nr_hugepages_store_common(bool obey_mempolicy, | 2466 | static 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 | ||
8350 | void free_contig_range(unsigned long pfn, unsigned nr_pages) | 8351 | void 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 | /* |