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>
This commit is contained in:
parent
62157e11d9
commit
32bf85c60c
|
@ -34,9 +34,9 @@ struct misc_cg;
|
||||||
* @events: Number of times, the resource limit exceeded.
|
* @events: Number of times, the resource limit exceeded.
|
||||||
*/
|
*/
|
||||||
struct misc_res {
|
struct misc_res {
|
||||||
unsigned long max;
|
u64 max;
|
||||||
atomic_long_t usage;
|
atomic64_t usage;
|
||||||
atomic_long_t events;
|
atomic64_t events;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,12 +54,10 @@ struct misc_cg {
|
||||||
struct misc_res res[MISC_CG_RES_TYPES];
|
struct misc_res res[MISC_CG_RES_TYPES];
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long misc_cg_res_total_usage(enum misc_res_type type);
|
u64 misc_cg_res_total_usage(enum misc_res_type type);
|
||||||
int misc_cg_set_capacity(enum misc_res_type type, unsigned long capacity);
|
int misc_cg_set_capacity(enum misc_res_type type, u64 capacity);
|
||||||
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
|
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount);
|
||||||
unsigned long amount);
|
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount);
|
||||||
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
|
|
||||||
unsigned long amount);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* css_misc() - Get misc cgroup from the css.
|
* css_misc() - Get misc cgroup from the css.
|
||||||
|
@ -100,27 +98,26 @@ static inline void put_misc_cg(struct misc_cg *cg)
|
||||||
|
|
||||||
#else /* !CONFIG_CGROUP_MISC */
|
#else /* !CONFIG_CGROUP_MISC */
|
||||||
|
|
||||||
static inline unsigned long misc_cg_res_total_usage(enum misc_res_type type)
|
static inline u64 misc_cg_res_total_usage(enum misc_res_type type)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int misc_cg_set_capacity(enum misc_res_type type,
|
static inline int misc_cg_set_capacity(enum misc_res_type type, u64 capacity)
|
||||||
unsigned long capacity)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int misc_cg_try_charge(enum misc_res_type type,
|
static inline int misc_cg_try_charge(enum misc_res_type type,
|
||||||
struct misc_cg *cg,
|
struct misc_cg *cg,
|
||||||
unsigned long amount)
|
u64 amount)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void misc_cg_uncharge(enum misc_res_type type,
|
static inline void misc_cg_uncharge(enum misc_res_type type,
|
||||||
struct misc_cg *cg,
|
struct misc_cg *cg,
|
||||||
unsigned long amount)
|
u64 amount)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/misc_cgroup.h>
|
#include <linux/misc_cgroup.h>
|
||||||
|
|
||||||
#define MAX_STR "max"
|
#define MAX_STR "max"
|
||||||
#define MAX_NUM ULONG_MAX
|
#define MAX_NUM U64_MAX
|
||||||
|
|
||||||
/* Miscellaneous res name, keep it in sync with enum misc_res_type */
|
/* Miscellaneous res name, keep it in sync with enum misc_res_type */
|
||||||
static const char *const misc_res_name[] = {
|
static const char *const misc_res_name[] = {
|
||||||
|
@ -37,7 +37,7 @@ static struct misc_cg root_cg;
|
||||||
* more than the actual capacity. We are using Limits resource distribution
|
* more than the actual capacity. We are using Limits resource distribution
|
||||||
* model of cgroup for miscellaneous controller.
|
* model of cgroup for miscellaneous controller.
|
||||||
*/
|
*/
|
||||||
static unsigned long misc_res_capacity[MISC_CG_RES_TYPES];
|
static u64 misc_res_capacity[MISC_CG_RES_TYPES];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* parent_misc() - Get the parent of the passed misc cgroup.
|
* parent_misc() - Get the parent of the passed misc cgroup.
|
||||||
|
@ -74,10 +74,10 @@ static inline bool valid_type(enum misc_res_type type)
|
||||||
* Context: Any context.
|
* Context: Any context.
|
||||||
* Return: Current total usage of the resource.
|
* Return: Current total usage of the resource.
|
||||||
*/
|
*/
|
||||||
unsigned long misc_cg_res_total_usage(enum misc_res_type type)
|
u64 misc_cg_res_total_usage(enum misc_res_type type)
|
||||||
{
|
{
|
||||||
if (valid_type(type))
|
if (valid_type(type))
|
||||||
return atomic_long_read(&root_cg.res[type].usage);
|
return atomic64_read(&root_cg.res[type].usage);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(misc_cg_res_total_usage);
|
||||||
* * %0 - Successfully registered the capacity.
|
* * %0 - Successfully registered the capacity.
|
||||||
* * %-EINVAL - If @type is invalid.
|
* * %-EINVAL - If @type is invalid.
|
||||||
*/
|
*/
|
||||||
int misc_cg_set_capacity(enum misc_res_type type, unsigned long capacity)
|
int misc_cg_set_capacity(enum misc_res_type type, u64 capacity)
|
||||||
{
|
{
|
||||||
if (!valid_type(type))
|
if (!valid_type(type))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -114,9 +114,9 @@ EXPORT_SYMBOL_GPL(misc_cg_set_capacity);
|
||||||
* Context: Any context.
|
* Context: Any context.
|
||||||
*/
|
*/
|
||||||
static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
|
static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
|
||||||
unsigned long amount)
|
u64 amount)
|
||||||
{
|
{
|
||||||
WARN_ONCE(atomic_long_add_negative(-amount, &cg->res[type].usage),
|
WARN_ONCE(atomic64_add_negative(-amount, &cg->res[type].usage),
|
||||||
"misc cgroup resource %s became less than 0",
|
"misc cgroup resource %s became less than 0",
|
||||||
misc_res_name[type]);
|
misc_res_name[type]);
|
||||||
}
|
}
|
||||||
|
@ -137,13 +137,12 @@ static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
|
||||||
* * -EBUSY - If max limit will be crossed or total usage will be more than the
|
* * -EBUSY - If max limit will be crossed or total usage will be more than the
|
||||||
* capacity.
|
* capacity.
|
||||||
*/
|
*/
|
||||||
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
|
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
|
||||||
unsigned long amount)
|
|
||||||
{
|
{
|
||||||
struct misc_cg *i, *j;
|
struct misc_cg *i, *j;
|
||||||
int ret;
|
int ret;
|
||||||
struct misc_res *res;
|
struct misc_res *res;
|
||||||
int new_usage;
|
s64 new_usage;
|
||||||
|
|
||||||
if (!(valid_type(type) && cg && READ_ONCE(misc_res_capacity[type])))
|
if (!(valid_type(type) && cg && READ_ONCE(misc_res_capacity[type])))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -154,7 +153,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
|
||||||
for (i = cg; i; i = parent_misc(i)) {
|
for (i = cg; i; i = parent_misc(i)) {
|
||||||
res = &i->res[type];
|
res = &i->res[type];
|
||||||
|
|
||||||
new_usage = atomic_long_add_return(amount, &res->usage);
|
new_usage = atomic64_add_return(amount, &res->usage);
|
||||||
if (new_usage > READ_ONCE(res->max) ||
|
if (new_usage > READ_ONCE(res->max) ||
|
||||||
new_usage > READ_ONCE(misc_res_capacity[type])) {
|
new_usage > READ_ONCE(misc_res_capacity[type])) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -165,7 +164,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
|
||||||
|
|
||||||
err_charge:
|
err_charge:
|
||||||
for (j = i; j; j = parent_misc(j)) {
|
for (j = i; j; j = parent_misc(j)) {
|
||||||
atomic_long_inc(&j->res[type].events);
|
atomic64_inc(&j->res[type].events);
|
||||||
cgroup_file_notify(&j->events_file);
|
cgroup_file_notify(&j->events_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(misc_cg_try_charge);
|
||||||
*
|
*
|
||||||
* Context: Any context.
|
* Context: Any context.
|
||||||
*/
|
*/
|
||||||
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
|
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
|
||||||
unsigned long amount)
|
|
||||||
{
|
{
|
||||||
struct misc_cg *i;
|
struct misc_cg *i;
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct misc_cg *cg = css_misc(seq_css(sf));
|
struct misc_cg *cg = css_misc(seq_css(sf));
|
||||||
unsigned long max;
|
u64 max;
|
||||||
|
|
||||||
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
||||||
if (READ_ONCE(misc_res_capacity[i])) {
|
if (READ_ONCE(misc_res_capacity[i])) {
|
||||||
|
@ -217,7 +215,7 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
|
||||||
if (max == MAX_NUM)
|
if (max == MAX_NUM)
|
||||||
seq_printf(sf, "%s max\n", misc_res_name[i]);
|
seq_printf(sf, "%s max\n", misc_res_name[i]);
|
||||||
else
|
else
|
||||||
seq_printf(sf, "%s %lu\n", misc_res_name[i],
|
seq_printf(sf, "%s %llu\n", misc_res_name[i],
|
||||||
max);
|
max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,13 +239,13 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
|
||||||
* Return:
|
* Return:
|
||||||
* * >= 0 - Number of bytes processed in the input.
|
* * >= 0 - Number of bytes processed in the input.
|
||||||
* * -EINVAL - If buf is not valid.
|
* * -EINVAL - If buf is not valid.
|
||||||
* * -ERANGE - If number is bigger than the unsigned long capacity.
|
* * -ERANGE - If number is bigger than the u64 capacity.
|
||||||
*/
|
*/
|
||||||
static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
|
static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
|
||||||
size_t nbytes, loff_t off)
|
size_t nbytes, loff_t off)
|
||||||
{
|
{
|
||||||
struct misc_cg *cg;
|
struct misc_cg *cg;
|
||||||
unsigned long max;
|
u64 max;
|
||||||
int ret = 0, i;
|
int ret = 0, i;
|
||||||
enum misc_res_type type = MISC_CG_RES_TYPES;
|
enum misc_res_type type = MISC_CG_RES_TYPES;
|
||||||
char *token;
|
char *token;
|
||||||
|
@ -271,7 +269,7 @@ static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
|
||||||
if (!strcmp(MAX_STR, buf)) {
|
if (!strcmp(MAX_STR, buf)) {
|
||||||
max = MAX_NUM;
|
max = MAX_NUM;
|
||||||
} else {
|
} else {
|
||||||
ret = kstrtoul(buf, 0, &max);
|
ret = kstrtou64(buf, 0, &max);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -297,13 +295,13 @@ static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
|
||||||
static int misc_cg_current_show(struct seq_file *sf, void *v)
|
static int misc_cg_current_show(struct seq_file *sf, void *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long usage;
|
u64 usage;
|
||||||
struct misc_cg *cg = css_misc(seq_css(sf));
|
struct misc_cg *cg = css_misc(seq_css(sf));
|
||||||
|
|
||||||
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
||||||
usage = atomic_long_read(&cg->res[i].usage);
|
usage = atomic64_read(&cg->res[i].usage);
|
||||||
if (READ_ONCE(misc_res_capacity[i]) || usage)
|
if (READ_ONCE(misc_res_capacity[i]) || usage)
|
||||||
seq_printf(sf, "%s %lu\n", misc_res_name[i], usage);
|
seq_printf(sf, "%s %llu\n", misc_res_name[i], usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -322,12 +320,12 @@ static int misc_cg_current_show(struct seq_file *sf, void *v)
|
||||||
static int misc_cg_capacity_show(struct seq_file *sf, void *v)
|
static int misc_cg_capacity_show(struct seq_file *sf, void *v)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long cap;
|
u64 cap;
|
||||||
|
|
||||||
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
||||||
cap = READ_ONCE(misc_res_capacity[i]);
|
cap = READ_ONCE(misc_res_capacity[i]);
|
||||||
if (cap)
|
if (cap)
|
||||||
seq_printf(sf, "%s %lu\n", misc_res_name[i], cap);
|
seq_printf(sf, "%s %llu\n", misc_res_name[i], cap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -336,12 +334,13 @@ static int misc_cg_capacity_show(struct seq_file *sf, void *v)
|
||||||
static int misc_events_show(struct seq_file *sf, void *v)
|
static int misc_events_show(struct seq_file *sf, void *v)
|
||||||
{
|
{
|
||||||
struct misc_cg *cg = css_misc(seq_css(sf));
|
struct misc_cg *cg = css_misc(seq_css(sf));
|
||||||
unsigned long events, i;
|
u64 events;
|
||||||
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
||||||
events = atomic_long_read(&cg->res[i].events);
|
events = atomic64_read(&cg->res[i].events);
|
||||||
if (READ_ONCE(misc_res_capacity[i]) || events)
|
if (READ_ONCE(misc_res_capacity[i]) || events)
|
||||||
seq_printf(sf, "%s.max %lu\n", misc_res_name[i], events);
|
seq_printf(sf, "%s.max %llu\n", misc_res_name[i], events);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -397,7 +396,7 @@ misc_cg_alloc(struct cgroup_subsys_state *parent_css)
|
||||||
|
|
||||||
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
for (i = 0; i < MISC_CG_RES_TYPES; i++) {
|
||||||
WRITE_ONCE(cg->res[i].max, MAX_NUM);
|
WRITE_ONCE(cg->res[i].max, MAX_NUM);
|
||||||
atomic_long_set(&cg->res[i].usage, 0);
|
atomic64_set(&cg->res[i].usage, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cg->css;
|
return &cg->css;
|
||||||
|
|
Loading…
Reference in New Issue