Skip to content

Commit 1adc4d4

Browse files
minatorvalds
authored andcommitted
hugetlb_cgroup: add interface for charge/uncharge hugetlb reservations
Augments hugetlb_cgroup_charge_cgroup to be able to charge hugetlb usage or hugetlb reservation counter. Adds a new interface to uncharge a hugetlb_cgroup counter via hugetlb_cgroup_uncharge_counter. Integrates the counter with hugetlb_cgroup, via hugetlb_cgroup_init, hugetlb_cgroup_have_usage, and hugetlb_cgroup_css_offline. Signed-off-by: Mina Almasry <almasrymina@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: Mike Kravetz <mike.kravetz@oracle.com> Acked-by: David Rientjes <rientjes@google.com> Cc: Greg Thelen <gthelen@google.com> Cc: Sandipan Das <sandipan@linux.ibm.com> Cc: Shakeel Butt <shakeelb@google.com> Cc: Shuah Khan <shuah@kernel.org> Link: http://lkml.kernel.org/r/20200211213128.73302-2-almasrymina@google.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent cdc2fcf commit 1adc4d4

File tree

3 files changed

+251
-48
lines changed

3 files changed

+251
-48
lines changed

include/linux/hugetlb_cgroup.h

Lines changed: 105 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,46 +20,92 @@
2020
struct hugetlb_cgroup;
2121
/*
2222
* Minimum page order trackable by hugetlb cgroup.
23-
* At least 3 pages are necessary for all the tracking information.
23+
* At least 4 pages are necessary for all the tracking information.
24+
* The second tail page (hpage[2]) is the fault usage cgroup.
25+
* The third tail page (hpage[3]) is the reservation usage cgroup.
2426
*/
2527
#define HUGETLB_CGROUP_MIN_ORDER 2
2628

2729
#ifdef CONFIG_CGROUP_HUGETLB
2830

29-
static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
31+
static inline struct hugetlb_cgroup *
32+
__hugetlb_cgroup_from_page(struct page *page, bool rsvd)
3033
{
3134
VM_BUG_ON_PAGE(!PageHuge(page), page);
3235

3336
if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
3437
return NULL;
35-
return (struct hugetlb_cgroup *)page[2].private;
38+
if (rsvd)
39+
return (struct hugetlb_cgroup *)page[3].private;
40+
else
41+
return (struct hugetlb_cgroup *)page[2].private;
42+
}
43+
44+
static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
45+
{
46+
return __hugetlb_cgroup_from_page(page, false);
3647
}
3748

38-
static inline
39-
int set_hugetlb_cgroup(struct page *page, struct hugetlb_cgroup *h_cg)
49+
static inline struct hugetlb_cgroup *
50+
hugetlb_cgroup_from_page_rsvd(struct page *page)
51+
{
52+
return __hugetlb_cgroup_from_page(page, true);
53+
}
54+
55+
static inline int __set_hugetlb_cgroup(struct page *page,
56+
struct hugetlb_cgroup *h_cg, bool rsvd)
4057
{
4158
VM_BUG_ON_PAGE(!PageHuge(page), page);
4259

4360
if (compound_order(page) < HUGETLB_CGROUP_MIN_ORDER)
4461
return -1;
45-
page[2].private = (unsigned long)h_cg;
62+
if (rsvd)
63+
page[3].private = (unsigned long)h_cg;
64+
else
65+
page[2].private = (unsigned long)h_cg;
4666
return 0;
4767
}
4868

69+
static inline int set_hugetlb_cgroup(struct page *page,
70+
struct hugetlb_cgroup *h_cg)
71+
{
72+
return __set_hugetlb_cgroup(page, h_cg, false);
73+
}
74+
75+
static inline int set_hugetlb_cgroup_rsvd(struct page *page,
76+
struct hugetlb_cgroup *h_cg)
77+
{
78+
return __set_hugetlb_cgroup(page, h_cg, true);
79+
}
80+
4981
static inline bool hugetlb_cgroup_disabled(void)
5082
{
5183
return !cgroup_subsys_enabled(hugetlb_cgrp_subsys);
5284
}
5385

5486
extern int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
5587
struct hugetlb_cgroup **ptr);
88+
extern int hugetlb_cgroup_charge_cgroup_rsvd(int idx, unsigned long nr_pages,
89+
struct hugetlb_cgroup **ptr);
5690
extern void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
5791
struct hugetlb_cgroup *h_cg,
5892
struct page *page);
93+
extern void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
94+
struct hugetlb_cgroup *h_cg,
95+
struct page *page);
5996
extern void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
6097
struct page *page);
98+
extern void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages,
99+
struct page *page);
100+
61101
extern void hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
62102
struct hugetlb_cgroup *h_cg);
103+
extern void hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
104+
struct hugetlb_cgroup *h_cg);
105+
extern void hugetlb_cgroup_uncharge_counter(struct page_counter *p,
106+
unsigned long nr_pages,
107+
struct cgroup_subsys_state *css);
108+
63109
extern void hugetlb_cgroup_file_init(void) __init;
64110
extern void hugetlb_cgroup_migrate(struct page *oldhpage,
65111
struct page *newhpage);
@@ -70,8 +116,26 @@ static inline struct hugetlb_cgroup *hugetlb_cgroup_from_page(struct page *page)
70116
return NULL;
71117
}
72118

73-
static inline
74-
int set_hugetlb_cgroup(struct page *page, struct hugetlb_cgroup *h_cg)
119+
static inline struct hugetlb_cgroup *
120+
hugetlb_cgroup_from_page_resv(struct page *page)
121+
{
122+
return NULL;
123+
}
124+
125+
static inline struct hugetlb_cgroup *
126+
hugetlb_cgroup_from_page_rsvd(struct page *page)
127+
{
128+
return NULL;
129+
}
130+
131+
static inline int set_hugetlb_cgroup(struct page *page,
132+
struct hugetlb_cgroup *h_cg)
133+
{
134+
return 0;
135+
}
136+
137+
static inline int set_hugetlb_cgroup_rsvd(struct page *page,
138+
struct hugetlb_cgroup *h_cg)
75139
{
76140
return 0;
77141
}
@@ -81,28 +145,51 @@ static inline bool hugetlb_cgroup_disabled(void)
81145
return true;
82146
}
83147

84-
static inline int
85-
hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
86-
struct hugetlb_cgroup **ptr)
148+
static inline int hugetlb_cgroup_charge_cgroup(int idx, unsigned long nr_pages,
149+
struct hugetlb_cgroup **ptr)
87150
{
88151
return 0;
89152
}
90153

91-
static inline void
92-
hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
93-
struct hugetlb_cgroup *h_cg,
94-
struct page *page)
154+
static inline int hugetlb_cgroup_charge_cgroup_rsvd(int idx,
155+
unsigned long nr_pages,
156+
struct hugetlb_cgroup **ptr)
157+
{
158+
return 0;
159+
}
160+
161+
static inline void hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
162+
struct hugetlb_cgroup *h_cg,
163+
struct page *page)
95164
{
96165
}
97166

98167
static inline void
99-
hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages, struct page *page)
168+
hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
169+
struct hugetlb_cgroup *h_cg,
170+
struct page *page)
171+
{
172+
}
173+
174+
static inline void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
175+
struct page *page)
176+
{
177+
}
178+
179+
static inline void hugetlb_cgroup_uncharge_page_rsvd(int idx,
180+
unsigned long nr_pages,
181+
struct page *page)
182+
{
183+
}
184+
static inline void hugetlb_cgroup_uncharge_cgroup(int idx,
185+
unsigned long nr_pages,
186+
struct hugetlb_cgroup *h_cg)
100187
{
101188
}
102189

103190
static inline void
104-
hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
105-
struct hugetlb_cgroup *h_cg)
191+
hugetlb_cgroup_uncharge_cgroup_rsvd(int idx, unsigned long nr_pages,
192+
struct hugetlb_cgroup *h_cg)
106193
{
107194
}
108195

mm/hugetlb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,7 @@ static void update_and_free_page(struct hstate *h, struct page *page)
10721072
1 << PG_writeback);
10731073
}
10741074
VM_BUG_ON_PAGE(hugetlb_cgroup_from_page(page), page);
1075+
VM_BUG_ON_PAGE(hugetlb_cgroup_from_page_rsvd(page), page);
10751076
set_compound_page_dtor(page, NULL_COMPOUND_DTOR);
10761077
set_page_refcounted(page);
10771078
if (hstate_is_gigantic(h)) {
@@ -1257,6 +1258,7 @@ static void prep_new_huge_page(struct hstate *h, struct page *page, int nid)
12571258
set_compound_page_dtor(page, HUGETLB_PAGE_DTOR);
12581259
spin_lock(&hugetlb_lock);
12591260
set_hugetlb_cgroup(page, NULL);
1261+
set_hugetlb_cgroup_rsvd(page, NULL);
12601262
h->nr_huge_pages++;
12611263
h->nr_huge_pages_node[nid]++;
12621264
spin_unlock(&hugetlb_lock);

0 commit comments

Comments
 (0)