Commit 32bf85c6 authored by Haitao Huang's avatar Haitao Huang Committed by Tejun Heo
Browse files

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: default avatarHaitao Huang <haitao.huang@linux.intel.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 62157e11
Loading
Loading
Loading
Loading
+11 −14
Original line number Diff line number Diff line
@@ -34,9 +34,9 @@ struct misc_cg;
 * @events: Number of times, the resource limit exceeded.
 */
struct misc_res {
	unsigned long max;
	atomic_long_t usage;
	atomic_long_t events;
	u64 max;
	atomic64_t usage;
	atomic64_t events;
};

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

unsigned long 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_try_charge(enum misc_res_type type, struct misc_cg *cg,
		       unsigned long amount);
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
		      unsigned long amount);
u64 misc_cg_res_total_usage(enum misc_res_type type);
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, u64 amount);
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount);

/**
 * 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 */

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;
}

static inline int misc_cg_set_capacity(enum misc_res_type type,
				       unsigned long capacity)
static inline int misc_cg_set_capacity(enum misc_res_type type, u64 capacity)
{
	return 0;
}

static inline int misc_cg_try_charge(enum misc_res_type type,
				     struct misc_cg *cg,
				     unsigned long amount)
				     u64 amount)
{
	return 0;
}

static inline void misc_cg_uncharge(enum misc_res_type type,
				    struct misc_cg *cg,
				    unsigned long amount)
				    u64 amount)
{
}

+27 −28
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
#include <linux/misc_cgroup.h>

#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 */
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
 * 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.
@@ -74,10 +74,10 @@ static inline bool valid_type(enum misc_res_type type)
 * Context: Any context.
 * 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))
		return atomic_long_read(&root_cg.res[type].usage);
		return atomic64_read(&root_cg.res[type].usage);

	return 0;
}
@@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(misc_cg_res_total_usage);
 * * %0 - Successfully registered the capacity.
 * * %-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))
		return -EINVAL;
@@ -114,9 +114,9 @@ EXPORT_SYMBOL_GPL(misc_cg_set_capacity);
 * Context: Any context.
 */
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_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
 *	      capacity.
 */
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
		       unsigned long amount)
int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
{
	struct misc_cg *i, *j;
	int ret;
	struct misc_res *res;
	int new_usage;
	s64 new_usage;

	if (!(valid_type(type) && cg && READ_ONCE(misc_res_capacity[type])))
		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)) {
		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) ||
		    new_usage > READ_ONCE(misc_res_capacity[type])) {
			ret = -EBUSY;
@@ -165,7 +164,7 @@ int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,

err_charge:
	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);
	}

@@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(misc_cg_try_charge);
 *
 * Context: Any context.
 */
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
		      unsigned long amount)
void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg, u64 amount)
{
	struct misc_cg *i;

@@ -209,7 +207,7 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
{
	int i;
	struct misc_cg *cg = css_misc(seq_css(sf));
	unsigned long max;
	u64 max;

	for (i = 0; i < MISC_CG_RES_TYPES; 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)
				seq_printf(sf, "%s max\n", misc_res_name[i]);
			else
				seq_printf(sf, "%s %lu\n", misc_res_name[i],
				seq_printf(sf, "%s %llu\n", misc_res_name[i],
					   max);
		}
	}
@@ -241,13 +239,13 @@ static int misc_cg_max_show(struct seq_file *sf, void *v)
 * Return:
 * * >= 0 - Number of bytes processed in the input.
 * * -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,
				 size_t nbytes, loff_t off)
{
	struct misc_cg *cg;
	unsigned long max;
	u64 max;
	int ret = 0, i;
	enum misc_res_type type = MISC_CG_RES_TYPES;
	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)) {
		max = MAX_NUM;
	} else {
		ret = kstrtoul(buf, 0, &max);
		ret = kstrtou64(buf, 0, &max);
		if (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)
{
	int i;
	unsigned long usage;
	u64 usage;
	struct misc_cg *cg = css_misc(seq_css(sf));

	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)
			seq_printf(sf, "%s %lu\n", misc_res_name[i], usage);
			seq_printf(sf, "%s %llu\n", misc_res_name[i], usage);
	}

	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)
{
	int i;
	unsigned long cap;
	u64 cap;

	for (i = 0; i < MISC_CG_RES_TYPES; i++) {
		cap = READ_ONCE(misc_res_capacity[i]);
		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;
@@ -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)
{
	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++) {
		events = atomic_long_read(&cg->res[i].events);
		events = atomic64_read(&cg->res[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;
}
@@ -397,7 +396,7 @@ misc_cg_alloc(struct cgroup_subsys_state *parent_css)

	for (i = 0; i < MISC_CG_RES_TYPES; i++) {
		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;