kernel/cgroup/misc.c:61 valid_type() warn: unsigned 'type' is never less than zero.

From: kernel test robot
Date: Sat Jun 12 2021 - 02:48:28 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: ad347abe4a9876b1f65f408ab467137e88f77eb4
commit: a72232eabdfcfe365a05a3eb392288b78d25a5ca cgroup: Add misc cgroup controller
date: 10 weeks ago
config: x86_64-randconfig-m001-20210611 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

smatch warnings:
kernel/cgroup/misc.c:61 valid_type() warn: unsigned 'type' is never less than zero.
kernel/cgroup/misc.c:210 misc_cg_max_show() warn: we never enter this loop
kernel/cgroup/misc.c:257 misc_cg_max_write() warn: we never enter this loop
kernel/cgroup/misc.c:299 misc_cg_current_show() warn: we never enter this loop
kernel/cgroup/misc.c:323 misc_cg_capacity_show() warn: we never enter this loop
kernel/cgroup/misc.c:376 misc_cg_alloc() warn: we never enter this loop
kernel/cgroup/misc.c:376 misc_cg_alloc() warn: unsigned 'i' is never less than zero.
kernel/cgroup/misc.c:376 misc_cg_alloc() warn: unsigned 'i' is never less than zero.

vim +/type +61 kernel/cgroup/misc.c

49
50 /**
51 * valid_type() - Check if @type is valid or not.
52 * @type: misc res type.
53 *
54 * Context: Any context.
55 * Return:
56 * * true - If valid type.
57 * * false - If not valid type.
58 */
59 static inline bool valid_type(enum misc_res_type type)
60 {
> 61 return type >= 0 && type < MISC_CG_RES_TYPES;
62 }
63
64 /**
65 * misc_cg_res_total_usage() - Get the current total usage of the resource.
66 * @type: misc res type.
67 *
68 * Context: Any context.
69 * Return: Current total usage of the resource.
70 */
71 unsigned long misc_cg_res_total_usage(enum misc_res_type type)
72 {
73 if (valid_type(type))
74 return atomic_long_read(&root_cg.res[type].usage);
75
76 return 0;
77 }
78 EXPORT_SYMBOL_GPL(misc_cg_res_total_usage);
79
80 /**
81 * misc_cg_set_capacity() - Set the capacity of the misc cgroup res.
82 * @type: Type of the misc res.
83 * @capacity: Supported capacity of the misc res on the host.
84 *
85 * If capacity is 0 then the charging a misc cgroup fails for that type.
86 *
87 * Context: Any context.
88 * Return:
89 * * %0 - Successfully registered the capacity.
90 * * %-EINVAL - If @type is invalid.
91 */
92 int misc_cg_set_capacity(enum misc_res_type type, unsigned long capacity)
93 {
94 if (!valid_type(type))
95 return -EINVAL;
96
97 WRITE_ONCE(misc_res_capacity[type], capacity);
98 return 0;
99 }
100 EXPORT_SYMBOL_GPL(misc_cg_set_capacity);
101
102 /**
103 * misc_cg_cancel_charge() - Cancel the charge from the misc cgroup.
104 * @type: Misc res type in misc cg to cancel the charge from.
105 * @cg: Misc cgroup to cancel charge from.
106 * @amount: Amount to cancel.
107 *
108 * Context: Any context.
109 */
110 static void misc_cg_cancel_charge(enum misc_res_type type, struct misc_cg *cg,
111 unsigned long amount)
112 {
113 WARN_ONCE(atomic_long_add_negative(-amount, &cg->res[type].usage),
114 "misc cgroup resource %s became less than 0",
115 misc_res_name[type]);
116 }
117
118 /**
119 * misc_cg_try_charge() - Try charging the misc cgroup.
120 * @type: Misc res type to charge.
121 * @cg: Misc cgroup which will be charged.
122 * @amount: Amount to charge.
123 *
124 * Charge @amount to the misc cgroup. Caller must use the same cgroup during
125 * the uncharge call.
126 *
127 * Context: Any context.
128 * Return:
129 * * %0 - If successfully charged.
130 * * -EINVAL - If @type is invalid or misc res has 0 capacity.
131 * * -EBUSY - If max limit will be crossed or total usage will be more than the
132 * capacity.
133 */
134 int misc_cg_try_charge(enum misc_res_type type, struct misc_cg *cg,
135 unsigned long amount)
136 {
137 struct misc_cg *i, *j;
138 int ret;
139 struct misc_res *res;
140 int new_usage;
141
142 if (!(valid_type(type) && cg && READ_ONCE(misc_res_capacity[type])))
143 return -EINVAL;
144
145 if (!amount)
146 return 0;
147
148 for (i = cg; i; i = parent_misc(i)) {
149 res = &i->res[type];
150
151 new_usage = atomic_long_add_return(amount, &res->usage);
152 if (new_usage > READ_ONCE(res->max) ||
153 new_usage > READ_ONCE(misc_res_capacity[type])) {
154 if (!res->failed) {
155 pr_info("cgroup: charge rejected by the misc controller for %s resource in ",
156 misc_res_name[type]);
157 pr_cont_cgroup_path(i->css.cgroup);
158 pr_cont("\n");
159 res->failed = true;
160 }
161 ret = -EBUSY;
162 goto err_charge;
163 }
164 }
165 return 0;
166
167 err_charge:
168 for (j = cg; j != i; j = parent_misc(j))
169 misc_cg_cancel_charge(type, j, amount);
170 misc_cg_cancel_charge(type, i, amount);
171 return ret;
172 }
173 EXPORT_SYMBOL_GPL(misc_cg_try_charge);
174
175 /**
176 * misc_cg_uncharge() - Uncharge the misc cgroup.
177 * @type: Misc res type which was charged.
178 * @cg: Misc cgroup which will be uncharged.
179 * @amount: Charged amount.
180 *
181 * Context: Any context.
182 */
183 void misc_cg_uncharge(enum misc_res_type type, struct misc_cg *cg,
184 unsigned long amount)
185 {
186 struct misc_cg *i;
187
188 if (!(amount && valid_type(type) && cg))
189 return;
190
191 for (i = cg; i; i = parent_misc(i))
192 misc_cg_cancel_charge(type, i, amount);
193 }
194 EXPORT_SYMBOL_GPL(misc_cg_uncharge);
195
196 /**
197 * misc_cg_max_show() - Show the misc cgroup max limit.
198 * @sf: Interface file
199 * @v: Arguments passed
200 *
201 * Context: Any context.
202 * Return: 0 to denote successful print.
203 */
204 static int misc_cg_max_show(struct seq_file *sf, void *v)
205 {
206 int i;
207 struct misc_cg *cg = css_misc(seq_css(sf));
208 unsigned long max;
209
> 210 for (i = 0; i < MISC_CG_RES_TYPES; i++) {
211 if (READ_ONCE(misc_res_capacity[i])) {
212 max = READ_ONCE(cg->res[i].max);
213 if (max == MAX_NUM)
214 seq_printf(sf, "%s max\n", misc_res_name[i]);
215 else
216 seq_printf(sf, "%s %lu\n", misc_res_name[i],
217 max);
218 }
219 }
220
221 return 0;
222 }
223
224 /**
225 * misc_cg_max_write() - Update the maximum limit of the cgroup.
226 * @of: Handler for the file.
227 * @buf: Data from the user. It should be either "max", 0, or a positive
228 * integer.
229 * @nbytes: Number of bytes of the data.
230 * @off: Offset in the file.
231 *
232 * User can pass data like:
233 * echo sev 23 > misc.max, OR
234 * echo sev max > misc.max
235 *
236 * Context: Any context.
237 * Return:
238 * * >= 0 - Number of bytes processed in the input.
239 * * -EINVAL - If buf is not valid.
240 * * -ERANGE - If number is bigger than the unsigned long capacity.
241 */
242 static ssize_t misc_cg_max_write(struct kernfs_open_file *of, char *buf,
243 size_t nbytes, loff_t off)
244 {
245 struct misc_cg *cg;
246 unsigned long max;
247 int ret = 0, i;
248 enum misc_res_type type = MISC_CG_RES_TYPES;
249 char *token;
250
251 buf = strstrip(buf);
252 token = strsep(&buf, " ");
253
254 if (!token || !buf)
255 return -EINVAL;
256
> 257 for (i = 0; i < MISC_CG_RES_TYPES; i++) {
258 if (!strcmp(misc_res_name[i], token)) {
259 type = i;
260 break;
261 }
262 }
263
264 if (type == MISC_CG_RES_TYPES)
265 return -EINVAL;
266
267 if (!strcmp(MAX_STR, buf)) {
268 max = MAX_NUM;
269 } else {
270 ret = kstrtoul(buf, 0, &max);
271 if (ret)
272 return ret;
273 }
274
275 cg = css_misc(of_css(of));
276
277 if (READ_ONCE(misc_res_capacity[type]))
278 WRITE_ONCE(cg->res[type].max, max);
279 else
280 ret = -EINVAL;
281
282 return ret ? ret : nbytes;
283 }
284

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip