aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNishanth Aravamudan <nacc@linux.vnet.ibm.com>2014-05-06 15:50:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-05-06 16:04:58 -0400
commit457c1b27ed56ec472d202731b12417bff023594a (patch)
treeed0c71d5171f02401ff15825d9a939ba3879a356
parent93030d83b9e1079836d82b46ab3ec671b1fdb623 (diff)
hugetlb: ensure hugepage access is denied if hugepages are not supported
Currently, I am seeing the following when I `mount -t hugetlbfs /none /dev/hugetlbfs`, and then simply do a `ls /dev/hugetlbfs`. I think it's related to the fact that hugetlbfs is properly not correctly setting itself up in this state?: Unable to handle kernel paging request for data at address 0x00000031 Faulting instruction address: 0xc000000000245710 Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=2048 NUMA pSeries .... In KVM guests on Power, in a guest not backed by hugepages, we see the following: AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 64 kB HPAGE_SHIFT == 0 in this configuration, which indicates that hugepages are not supported at boot-time, but this is only checked in hugetlb_init(). Extract the check to a helper function, and use it in a few relevant places. This does make hugetlbfs not supported (not registered at all) in this environment. I believe this is fine, as there are no valid hugepages and that won't change at runtime. [akpm@linux-foundation.org: use pr_info(), per Mel] [akpm@linux-foundation.org: fix build when HPAGE_SHIFT is undefined] Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Acked-by: Mel Gorman <mgorman@suse.de> Cc: Randy Dunlap <rdunlap@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/hugetlbfs/inode.c5
-rw-r--r--include/linux/hugetlb.h10
-rw-r--r--mm/hugetlb.c19
3 files changed, 29 insertions, 5 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 204027520937..e19d4c0cacae 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -1030,6 +1030,11 @@ static int __init init_hugetlbfs_fs(void)
1030 int error; 1030 int error;
1031 int i; 1031 int i;
1032 1032
1033 if (!hugepages_supported()) {
1034 pr_info("hugetlbfs: disabling because there are no supported hugepage sizes\n");
1035 return -ENOTSUPP;
1036 }
1037
1033 error = bdi_init(&hugetlbfs_backing_dev_info); 1038 error = bdi_init(&hugetlbfs_backing_dev_info);
1034 if (error) 1039 if (error)
1035 return error; 1040 return error;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 5b337cf8fb86..b65166de1d9d 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -412,6 +412,16 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
412 return &mm->page_table_lock; 412 return &mm->page_table_lock;
413} 413}
414 414
415static inline bool hugepages_supported(void)
416{
417 /*
418 * Some platform decide whether they support huge pages at boot
419 * time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when
420 * there is no such support
421 */
422 return HPAGE_SHIFT != 0;
423}
424
415#else /* CONFIG_HUGETLB_PAGE */ 425#else /* CONFIG_HUGETLB_PAGE */
416struct hstate {}; 426struct hstate {};
417#define alloc_huge_page_node(h, nid) NULL 427#define alloc_huge_page_node(h, nid) NULL
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 246192929a2d..c82290b9c1fc 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1981,11 +1981,7 @@ static int __init hugetlb_init(void)
1981{ 1981{
1982 int i; 1982 int i;
1983 1983
1984 /* Some platform decide whether they support huge pages at boot 1984 if (!hugepages_supported())
1985 * time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when
1986 * there is no such support
1987 */
1988 if (HPAGE_SHIFT == 0)
1989 return 0; 1985 return 0;
1990 1986
1991 if (!size_to_hstate(default_hstate_size)) { 1987 if (!size_to_hstate(default_hstate_size)) {
@@ -2112,6 +2108,9 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
2112 unsigned long tmp; 2108 unsigned long tmp;
2113 int ret; 2109 int ret;
2114 2110
2111 if (!hugepages_supported())
2112 return -ENOTSUPP;
2113
2115 tmp = h->max_huge_pages; 2114 tmp = h->max_huge_pages;
2116 2115
2117 if (write && h->order >= MAX_ORDER) 2116 if (write && h->order >= MAX_ORDER)
@@ -2165,6 +2164,9 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write,
2165 unsigned long tmp; 2164 unsigned long tmp;
2166 int ret; 2165 int ret;
2167 2166
2167 if (!hugepages_supported())
2168 return -ENOTSUPP;
2169
2168 tmp = h->nr_overcommit_huge_pages; 2170 tmp = h->nr_overcommit_huge_pages;
2169 2171
2170 if (write && h->order >= MAX_ORDER) 2172 if (write && h->order >= MAX_ORDER)
@@ -2190,6 +2192,8 @@ out:
2190void hugetlb_report_meminfo(struct seq_file *m) 2192void hugetlb_report_meminfo(struct seq_file *m)
2191{ 2193{
2192 struct hstate *h = &default_hstate; 2194 struct hstate *h = &default_hstate;
2195 if (!hugepages_supported())
2196 return;
2193 seq_printf(m, 2197 seq_printf(m,
2194 "HugePages_Total: %5lu\n" 2198 "HugePages_Total: %5lu\n"
2195 "HugePages_Free: %5lu\n" 2199 "HugePages_Free: %5lu\n"
@@ -2206,6 +2210,8 @@ void hugetlb_report_meminfo(struct seq_file *m)
2206int hugetlb_report_node_meminfo(int nid, char *buf) 2210int hugetlb_report_node_meminfo(int nid, char *buf)
2207{ 2211{
2208 struct hstate *h = &default_hstate; 2212 struct hstate *h = &default_hstate;
2213 if (!hugepages_supported())
2214 return 0;
2209 return sprintf(buf, 2215 return sprintf(buf,
2210 "Node %d HugePages_Total: %5u\n" 2216 "Node %d HugePages_Total: %5u\n"
2211 "Node %d HugePages_Free: %5u\n" 2217 "Node %d HugePages_Free: %5u\n"
@@ -2220,6 +2226,9 @@ void hugetlb_show_meminfo(void)
2220 struct hstate *h; 2226 struct hstate *h;
2221 int nid; 2227 int nid;
2222 2228
2229 if (!hugepages_supported())
2230 return;
2231
2223 for_each_node_state(nid, N_MEMORY) 2232 for_each_node_state(nid, N_MEMORY)
2224 for_each_hstate(h) 2233 for_each_hstate(h)
2225 pr_info("Node %d hugepages_total=%u hugepages_free=%u hugepages_surp=%u hugepages_size=%lukB\n", 2234 pr_info("Node %d hugepages_total=%u hugepages_free=%u hugepages_surp=%u hugepages_size=%lukB\n",