tree: https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git for-next head: d95af61df072a7d70b311a11c0c24cf7d8ccebd9 commit: a72232eabdfcfe365a05a3eb392288b78d25a5ca [1/5] cgroup: Add misc cgroup controller config: parisc-randconfig-m031-20210413 (attached as .config) compiler: hppa-linux-gcc (GCC) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot 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(a)lists.01.org