hugetlb_cgroup.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. *
  3. * Copyright IBM Corporation, 2012
  4. * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of version 2.1 of the GNU Lesser General Public License
  8. * as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it would be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. */
  15. #include <linux/cgroup.h>
  16. #include <linux/slab.h>
  17. #include <linux/hugetlb.h>
  18. #include <linux/hugetlb_cgroup.h>
  19. struct hugetlb_cgroup {
  20. struct cgroup_subsys_state css;
  21. /*
  22. * the counter to account for hugepages from hugetlb.
  23. */
  24. struct res_counter hugepage[HUGE_MAX_HSTATE];
  25. };
  26. struct cgroup_subsys hugetlb_subsys __read_mostly;
  27. static struct hugetlb_cgroup *root_h_cgroup __read_mostly;
  28. static inline
  29. struct hugetlb_cgroup *hugetlb_cgroup_from_css(struct cgroup_subsys_state *s)
  30. {
  31. return container_of(s, struct hugetlb_cgroup, css);
  32. }
  33. static inline
  34. struct hugetlb_cgroup *hugetlb_cgroup_from_cgroup(struct cgroup *cgroup)
  35. {
  36. return hugetlb_cgroup_from_css(cgroup_subsys_state(cgroup,
  37. hugetlb_subsys_id));
  38. }
  39. static inline
  40. struct hugetlb_cgroup *hugetlb_cgroup_from_task(struct task_struct *task)
  41. {
  42. return hugetlb_cgroup_from_css(task_subsys_state(task,
  43. hugetlb_subsys_id));
  44. }
  45. static inline bool hugetlb_cgroup_is_root(struct hugetlb_cgroup *h_cg)
  46. {
  47. return (h_cg == root_h_cgroup);
  48. }
  49. static inline struct hugetlb_cgroup *parent_hugetlb_cgroup(struct cgroup *cg)
  50. {
  51. if (!cg->parent)
  52. return NULL;
  53. return hugetlb_cgroup_from_cgroup(cg->parent);
  54. }
  55. static inline bool hugetlb_cgroup_have_usage(struct cgroup *cg)
  56. {
  57. int idx;
  58. struct hugetlb_cgroup *h_cg = hugetlb_cgroup_from_cgroup(cg);
  59. for (idx = 0; idx < hugetlb_max_hstate; idx++) {
  60. if ((res_counter_read_u64(&h_cg->hugepage[idx], RES_USAGE)) > 0)
  61. return true;
  62. }
  63. return false;
  64. }
  65. static struct cgroup_subsys_state *hugetlb_cgroup_create(struct cgroup *cgroup)
  66. {
  67. int idx;
  68. struct cgroup *parent_cgroup;
  69. struct hugetlb_cgroup *h_cgroup, *parent_h_cgroup;
  70. h_cgroup = kzalloc(sizeof(*h_cgroup), GFP_KERNEL);
  71. if (!h_cgroup)
  72. return ERR_PTR(-ENOMEM);
  73. parent_cgroup = cgroup->parent;
  74. if (parent_cgroup) {
  75. parent_h_cgroup = hugetlb_cgroup_from_cgroup(parent_cgroup);
  76. for (idx = 0; idx < HUGE_MAX_HSTATE; idx++)
  77. res_counter_init(&h_cgroup->hugepage[idx],
  78. &parent_h_cgroup->hugepage[idx]);
  79. } else {
  80. root_h_cgroup = h_cgroup;
  81. for (idx = 0; idx < HUGE_MAX_HSTATE; idx++)
  82. res_counter_init(&h_cgroup->hugepage[idx], NULL);
  83. }
  84. return &h_cgroup->css;
  85. }
  86. static void hugetlb_cgroup_destroy(struct cgroup *cgroup)
  87. {
  88. struct hugetlb_cgroup *h_cgroup;
  89. h_cgroup = hugetlb_cgroup_from_cgroup(cgroup);
  90. kfree(h_cgroup);
  91. }
  92. static int hugetlb_cgroup_pre_destroy(struct cgroup *cgroup)
  93. {
  94. /* We will add the cgroup removal support in later patches */
  95. return -EBUSY;
  96. }
  97. struct cgroup_subsys hugetlb_subsys = {
  98. .name = "hugetlb",
  99. .create = hugetlb_cgroup_create,
  100. .pre_destroy = hugetlb_cgroup_pre_destroy,
  101. .destroy = hugetlb_cgroup_destroy,
  102. .subsys_id = hugetlb_subsys_id,
  103. };