Skip to content

Commit 32bf85c

Browse files
haitaohuanghtejun
authored andcommitted
cgroup/misc: Change counters to be explicit 64bit types
So the variables can account for resources of huge quantities even on 32-bit machines. Signed-off-by: Haitao Huang <haitao.huang@linux.intel.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent 62157e1 commit 32bf85c

2 files changed

Lines changed: 38 additions & 42 deletions

File tree

include/linux/misc_cgroup.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ struct misc_cg;
3434
* @events: Number of times, the resource limit exceeded.
3535
*/
3636
struct misc_res {
37-
unsigned long max;
38-
atomic_long_t usage;
39-
atomic_long_t events;
37+
u64 max;
38+
atomic64_t usage;
39+
atomic64_t events;
4040
};
4141

4242
/**
@@ -54,12 +54,10 @@ struct misc_cg {
5454
struct misc_res res[MISC_CG_RES_TYPES];
5555
};
5656

57-
unsigned long misc_cg_res_total_usage(enum misc_res_type type);
58-
int misc_cg_set_capacity(enum misc_res_type type, unsigned long capacity);
59-
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
60-
unsigned long amount);
61-
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
62-
unsigned long amount);
57+
u64 misc_cg_res_total_usage(enum misc_res_type type);
58+
int misc_cg_set_capacity(enum misc_res_type type, u64 capacity);
59+
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount);
60+
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount);
6361

6462
/**
6563
* css_misc() - Get misc cgroup from the css.
@@ -100,27 +98,26 @@ static inline void put_misc_cg(struct misc_cg *cg)
10098

10199
#else /* !CONFIG_CGROUP_MISC */
102100

103-
static inline unsigned long misc_cg_res_total_usage(enum misc_res_type type)
101+
static inline u64 misc_cg_res_total_usage(enum misc_res_type type)
104102
{
105103
return 0;
106104
}
107105

108-
static inline int misc_cg_set_capacity(enum misc_res_type type,
109-
unsigned long capacity)
106+
static inline int misc_cg_set_capacity(enum misc_res_type type, u64 capacity)
110107
{
111108
return 0;
112109
}
113110

114111
static inline int misc_cg_try_charge(enum misc_res_type type,
115112
struct misc_cg *cg,
116-
unsigned long amount)
113+
u64 amount)
117114
{
118115
return 0;
119116
}
120117

121118
static inline void misc_cg_uncharge(enum misc_res_type type,
122119
struct misc_cg *cg,
123-
unsigned long amount)
120+
u64 amount)
124121
{
125122
}
126123

kernel/cgroup/misc.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <linux/misc_cgroup.h>
1515

1616
#define MAX_STR "max"
17-
#define MAX_NUM ULONG_MAX
17+
#define MAX_NUM U64_MAX
1818

1919
/* Miscellaneous res name, keep it in sync with enum misc_res_type */
2020
static const char *const misc_res_name[] = {
@@ -37,7 +37,7 @@ static struct misc_cg root_cg;
3737
* more than the actual capacity. We are using Limits resource distribution
3838
* model of cgroup for miscellaneous controller.
3939
*/
40-
static unsigned long misc_res_capacity[MISC_CG_RES_TYPES];
40+
static u64 misc_res_capacity[MISC_CG_RES_TYPES];
4141

4242
/**
4343
* parent_misc() - Get the parent of the passed misc cgroup.
@@ -74,10 +74,10 @@ static inline bool valid_type(enum misc_res_type type)
7474
* Context: Any context.
7575
* Return: Current total usage of the resource.
7676
*/
77-
unsigned long misc_cg_res_total_usage(enum misc_res_type type)
77+
u64 misc_cg_res_total_usage(enum misc_res_type type)
7878
{
7979
if (valid_type(type))
80-
return atomic_long_read(&root_cg.res[type].usage);
80+
return atomic64_read(&root_cg.res[type].usage);
8181

8282
return 0;
8383
}
@@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(misc_cg_res_total_usage);
9595
* * %0 - Successfully registered the capacity.
9696
* * %-EINVAL - If @type is invalid.
9797
*/
98-
int misc_cg_set_capacity(enum misc_res_type type, unsigned long capacity)
98+
int misc_cg_set_capacity(enum misc_res_type type, u64 capacity)
9999
{
100100
if (!valid_type(type))
101101
return -EINVAL;
@@ -114,9 +114,9 @@ EXPORT_SYMBOL_GPL(misc_cg_set_capacity);
114114
* Context: Any context.
115115
*/
116116
static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
117-
unsigned long amount)
117+
u64 amount)
118118
{
119-
WARN_ONCE(atomic_long_add_negative(-amount, &cg->res[type].usage),
119+
WARN_ONCE(atomic64_add_negative(-amount, &cg->res[type].usage),
120120
"misc cgroup resource %s became less than 0",
121121
misc_res_name[type]);
122122
}
@@ -137,13 +137,12 @@ static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
137137
* * -EBUSY - If max limit will be crossed or total usage will be more than the
138138
* capacity.
139139
*/
140-
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
141-
unsigned long amount)
140+
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
142141
{
143142
struct misc_cg *i, *j;
144143
int ret;
145144
struct misc_res *res;
146-
int new_usage;
145+
s64 new_usage;
147146

148147
if (!(valid_type(type) && cg && READ_ONCE(misc_res_capacity[type])))
149148
return -EINVAL;
@@ -154,7 +153,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
154153
for (i = cg; i; i = parent_misc(i)) {
155154
res = &i->res[type];
156155

157-
new_usage = atomic_long_add_return(amount, &res->usage);
156+
new_usage = atomic64_add_return(amount, &res->usage);
158157
if (new_usage > READ_ONCE(res->max) ||
159158
new_usage > READ_ONCE(misc_res_capacity[type])) {
160159
ret = -EBUSY;
@@ -165,7 +164,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
165164

166165
err_charge:
167166
for (j = i; j; j = parent_misc(j)) {
168-
atomic_long_inc(&j->res[type].events);
167+
atomic64_inc(&j->res[type].events);
169168
cgroup_file_notify(&j->events_file);
170169
}
171170

@@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(misc_cg_try_charge);
184183
*
185184
* Context: Any context.
186185
*/
187-
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
188-
unsigned long amount)
186+
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
189187
{
190188
struct misc_cg *i;
191189

@@ -209,15 +207,15 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
209207
{
210208
int i;
211209
struct misc_cg *cg = css_misc(seq_css(sf));
212-
unsigned long max;
210+
u64 max;
213211

214212
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
215213
if (READ_ONCE(misc_res_capacity[i])) {
216214
max = READ_ONCE(cg->res[i].max);
217215
if (max == MAX_NUM)
218216
seq_printf(sf, "%s max\n", misc_res_name[i]);
219217
else
220-
seq_printf(sf, "%s %lu\n", misc_res_name[i],
218+
seq_printf(sf, "%s %llu\n", misc_res_name[i],
221219
max);
222220
}
223221
}
@@ -241,13 +239,13 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
241239
* Return:
242240
* * >= 0 - Number of bytes processed in the input.
243241
* * -EINVAL - If buf is not valid.
244-
* * -ERANGE - If number is bigger than the unsigned long capacity.
242+
* * -ERANGE - If number is bigger than the u64 capacity.
245243
*/
246244
static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
247245
size_t nbytes, loff_t off)
248246
{
249247
struct misc_cg *cg;
250-
unsigned long max;
248+
u64 max;
251249
int ret = 0, i;
252250
enum misc_res_type type = MISC_CG_RES_TYPES;
253251
char *token;
@@ -271,7 +269,7 @@ static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
271269
if (!strcmp(MAX_STR, buf)) {
272270
max = MAX_NUM;
273271
} else {
274-
ret = kstrtoul(buf, 0, &max);
272+
ret = kstrtou64(buf, 0, &max);
275273
if (ret)
276274
return ret;
277275
}
@@ -297,13 +295,13 @@ static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
297295
static int misc_cg_current_show(struct seq_file *sf, void *v)
298296
{
299297
int i;
300-
unsigned long usage;
298+
u64 usage;
301299
struct misc_cg *cg = css_misc(seq_css(sf));
302300

303301
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
304-
usage = atomic_long_read(&cg->res[i].usage);
302+
usage = atomic64_read(&cg->res[i].usage);
305303
if (READ_ONCE(misc_res_capacity[i]) || usage)
306-
seq_printf(sf, "%s %lu\n", misc_res_name[i], usage);
304+
seq_printf(sf, "%s %llu\n", misc_res_name[i], usage);
307305
}
308306

309307
return 0;
@@ -322,12 +320,12 @@ static int misc_cg_current_show(struct seq_file *sf, void *v)
322320
static int misc_cg_capacity_show(struct seq_file *sf, void *v)
323321
{
324322
int i;
325-
unsigned long cap;
323+
u64 cap;
326324

327325
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
328326
cap = READ_ONCE(misc_res_capacity[i]);
329327
if (cap)
330-
seq_printf(sf, "%s %lu\n", misc_res_name[i], cap);
328+
seq_printf(sf, "%s %llu\n", misc_res_name[i], cap);
331329
}
332330

333331
return 0;
@@ -336,12 +334,13 @@ static int misc_cg_capacity_show(struct seq_file *sf, void *v)
336334
static int misc_events_show(struct seq_file *sf, void *v)
337335
{
338336
struct misc_cg *cg = css_misc(seq_css(sf));
339-
unsigned long events, i;
337+
u64 events;
338+
int i;
340339

341340
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
342-
events = atomic_long_read(&cg->res[i].events);
341+
events = atomic64_read(&cg->res[i].events);
343342
if (READ_ONCE(misc_res_capacity[i]) || events)
344-
seq_printf(sf, "%s.max %lu\n", misc_res_name[i], events);
343+
seq_printf(sf, "%s.max %llu\n", misc_res_name[i], events);
345344
}
346345
return 0;
347346
}
@@ -397,7 +396,7 @@ misc_cg_alloc(struct cgroup_subsys_state *parent_css)
397396

398397
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
399398
WRITE_ONCE(cg->res[i].max, MAX_NUM);
400-
atomic_long_set(&cg->res[i].usage, 0);
399+
atomic64_set(&cg->res[i].usage, 0);
401400
}
402401

403402
return &cg->css;

0 commit comments

Comments
 (0)