Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * HugeTLB sysfs interfaces.
4 * (C) Nadia Yvette Chambers, April 2004
5 */
6
7#include <linux/sysctl.h>
8
9#include "hugetlb_internal.h"
10
11#ifdef CONFIG_SYSCTL
12static int proc_hugetlb_doulongvec_minmax(const struct ctl_table *table, int write,
13 void *buffer, size_t *length,
14 loff_t *ppos, unsigned long *out)
15{
16 struct ctl_table dup_table;
17
18 /*
19 * In order to avoid races with __do_proc_doulongvec_minmax(), we
20 * can duplicate the @table and alter the duplicate of it.
21 */
22 dup_table = *table;
23 dup_table.data = out;
24
25 return proc_doulongvec_minmax(&dup_table, write, buffer, length, ppos);
26}
27
28static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
29 const struct ctl_table *table, int write,
30 void *buffer, size_t *length, loff_t *ppos)
31{
32 struct hstate *h = &default_hstate;
33 unsigned long tmp = h->max_huge_pages;
34 int ret;
35
36 if (!hugepages_supported())
37 return -EOPNOTSUPP;
38
39 ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos,
40 &tmp);
41 if (ret)
42 goto out;
43
44 if (write)
45 ret = __nr_hugepages_store_common(obey_mempolicy, h,
46 NUMA_NO_NODE, tmp, *length);
47out:
48 return ret;
49}
50
51static int hugetlb_sysctl_handler(const struct ctl_table *table, int write,
52 void *buffer, size_t *length, loff_t *ppos)
53{
54
55 return hugetlb_sysctl_handler_common(false, table, write,
56 buffer, length, ppos);
57}
58
59#ifdef CONFIG_NUMA
60static int hugetlb_mempolicy_sysctl_handler(const struct ctl_table *table, int write,
61 void *buffer, size_t *length, loff_t *ppos)
62{
63 return hugetlb_sysctl_handler_common(true, table, write,
64 buffer, length, ppos);
65}
66#endif /* CONFIG_NUMA */
67
68static int hugetlb_overcommit_handler(const struct ctl_table *table, int write,
69 void *buffer, size_t *length, loff_t *ppos)
70{
71 struct hstate *h = &default_hstate;
72 unsigned long tmp;
73 int ret;
74
75 if (!hugepages_supported())
76 return -EOPNOTSUPP;
77
78 tmp = h->nr_overcommit_huge_pages;
79
80 if (write && hstate_is_gigantic_no_runtime(h))
81 return -EINVAL;
82
83 ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos,
84 &tmp);
85 if (ret)
86 goto out;
87
88 if (write) {
89 spin_lock_irq(&hugetlb_lock);
90 h->nr_overcommit_huge_pages = tmp;
91 spin_unlock_irq(&hugetlb_lock);
92 }
93out:
94 return ret;
95}
96
97static const struct ctl_table hugetlb_table[] = {
98 {
99 .procname = "nr_hugepages",
100 .data = NULL,
101 .maxlen = sizeof(unsigned long),
102 .mode = 0644,
103 .proc_handler = hugetlb_sysctl_handler,
104 },
105#ifdef CONFIG_NUMA
106 {
107 .procname = "nr_hugepages_mempolicy",
108 .data = NULL,
109 .maxlen = sizeof(unsigned long),
110 .mode = 0644,
111 .proc_handler = &hugetlb_mempolicy_sysctl_handler,
112 },
113#endif
114 {
115 .procname = "hugetlb_shm_group",
116 .data = &sysctl_hugetlb_shm_group,
117 .maxlen = sizeof(gid_t),
118 .mode = 0644,
119 .proc_handler = proc_dointvec,
120 },
121 {
122 .procname = "nr_overcommit_hugepages",
123 .data = NULL,
124 .maxlen = sizeof(unsigned long),
125 .mode = 0644,
126 .proc_handler = hugetlb_overcommit_handler,
127 },
128};
129
130void __init hugetlb_sysctl_init(void)
131{
132 register_sysctl_init("vm", hugetlb_table);
133}
134#endif /* CONFIG_SYSCTL */