| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * HugeTLB sysfs interfaces.
- * (C) Nadia Yvette Chambers, April 2004
- */
- #include <linux/sysctl.h>
- #include "hugetlb_internal.h"
- int movable_gigantic_pages;
- #ifdef CONFIG_SYSCTL
- static int proc_hugetlb_doulongvec_minmax(const struct ctl_table *table, int write,
- void *buffer, size_t *length,
- loff_t *ppos, unsigned long *out)
- {
- struct ctl_table dup_table;
- /*
- * In order to avoid races with __do_proc_doulongvec_minmax(), we
- * can duplicate the @table and alter the duplicate of it.
- */
- dup_table = *table;
- dup_table.data = out;
- return proc_doulongvec_minmax(&dup_table, write, buffer, length, ppos);
- }
- static int hugetlb_sysctl_handler_common(bool obey_mempolicy,
- const struct ctl_table *table, int write,
- void *buffer, size_t *length, loff_t *ppos)
- {
- struct hstate *h = &default_hstate;
- unsigned long tmp = h->max_huge_pages;
- int ret;
- if (!hugepages_supported())
- return -EOPNOTSUPP;
- ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos,
- &tmp);
- if (ret)
- goto out;
- if (write)
- ret = __nr_hugepages_store_common(obey_mempolicy, h,
- NUMA_NO_NODE, tmp, *length);
- out:
- return ret;
- }
- static int hugetlb_sysctl_handler(const struct ctl_table *table, int write,
- void *buffer, size_t *length, loff_t *ppos)
- {
- return hugetlb_sysctl_handler_common(false, table, write,
- buffer, length, ppos);
- }
- #ifdef CONFIG_NUMA
- static int hugetlb_mempolicy_sysctl_handler(const struct ctl_table *table, int write,
- void *buffer, size_t *length, loff_t *ppos)
- {
- return hugetlb_sysctl_handler_common(true, table, write,
- buffer, length, ppos);
- }
- #endif /* CONFIG_NUMA */
- static int hugetlb_overcommit_handler(const struct ctl_table *table, int write,
- void *buffer, size_t *length, loff_t *ppos)
- {
- struct hstate *h = &default_hstate;
- unsigned long tmp;
- int ret;
- if (!hugepages_supported())
- return -EOPNOTSUPP;
- tmp = h->nr_overcommit_huge_pages;
- if (write && hstate_is_gigantic_no_runtime(h))
- return -EINVAL;
- ret = proc_hugetlb_doulongvec_minmax(table, write, buffer, length, ppos,
- &tmp);
- if (ret)
- goto out;
- if (write) {
- spin_lock_irq(&hugetlb_lock);
- h->nr_overcommit_huge_pages = tmp;
- spin_unlock_irq(&hugetlb_lock);
- }
- out:
- return ret;
- }
- static const struct ctl_table hugetlb_table[] = {
- {
- .procname = "nr_hugepages",
- .data = NULL,
- .maxlen = sizeof(unsigned long),
- .mode = 0644,
- .proc_handler = hugetlb_sysctl_handler,
- },
- #ifdef CONFIG_NUMA
- {
- .procname = "nr_hugepages_mempolicy",
- .data = NULL,
- .maxlen = sizeof(unsigned long),
- .mode = 0644,
- .proc_handler = &hugetlb_mempolicy_sysctl_handler,
- },
- #endif
- {
- .procname = "hugetlb_shm_group",
- .data = &sysctl_hugetlb_shm_group,
- .maxlen = sizeof(gid_t),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- {
- .procname = "nr_overcommit_hugepages",
- .data = NULL,
- .maxlen = sizeof(unsigned long),
- .mode = 0644,
- .proc_handler = hugetlb_overcommit_handler,
- },
- #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
- {
- .procname = "movable_gigantic_pages",
- .data = &movable_gigantic_pages,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = proc_dointvec,
- },
- #endif
- };
- void __init hugetlb_sysctl_init(void)
- {
- register_sysctl_init("vm", hugetlb_table);
- }
- #endif /* CONFIG_SYSCTL */
|