hugetlb_sysctl.c 3.3 KB

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