cgroup/misc: Change counters to be explicit 64bit types
authorHaitao Huang <haitao.huang@linux.intel.com>
Tue, 18 Jul 2023 01:08:45 +0000 (18:08 -0700)
committerTejun Heo <tj@kernel.org>
Tue, 18 Jul 2023 22:10:00 +0000 (12:10 -1000)
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>
include/linux/misc_cgroup.h
kernel/cgroup/misc.c

index 6555c0f..e799b1f 100644 (file)
@@ -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)
 {
 }
 
index ae2f4dd..abbe9aa 100644 (file)
@@ -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;