[morse:mpam/snapshot/v5.15 62/139] fs/resctrl/monitor.c:102 __check_limbo() warn: unsigned 'arch_mon_ctx' is never less than zero.

From: kernel test robot
Date: Fri Nov 19 2021 - 06:54:56 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git mpam/snapshot/v5.15
head: ce3629841262f725a5f3a327403fcaf0e604a85e
commit: 016782894eb4694b95d6b67f4b1794cde795482c [62/139] x86/resctrl: Move the restrl code to fs
config: x86_64-randconfig-m001-20211115 (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>

New smatch warnings:
fs/resctrl/monitor.c:102 __check_limbo() warn: unsigned 'arch_mon_ctx' is never less than zero.
fs/resctrl/monitor.c:238 add_rmid_to_limbo() warn: unsigned 'arch_mon_ctx' is never less than zero.
fs/resctrl/monitor.c:369 mon_event_count() warn: unsigned 'rr->arch_mon_ctx' is never less than zero.
fs/resctrl/monitor.c:537 mbm_update() warn: unsigned 'rr.arch_mon_ctx' is never less than zero.
fs/resctrl/rdtgroup.c:3011 rdtgroup_mkdir_ctrl_mon() error: uninitialized symbol 'rmid'.

Old smatch warnings:
fs/resctrl/monitor.c:547 mbm_update() warn: unsigned 'rr.arch_mon_ctx' is never less than zero.

vim +/arch_mon_ctx +102 fs/resctrl/monitor.c

84
85 /*
86 * Check the RMIDs that are marked as busy for this domain. If the
87 * reported LLC occupancy is below the threshold clear the busy bit and
88 * decrement the count. If the busy count gets to zero on an RMID, we
89 * free the RMID
90 */
91 void __check_limbo(struct rdt_domain *d, bool force_free)
92 {
93 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
94 u32 idx_limit = resctrl_arch_system_num_rmid_idx();
95 unsigned long arch_mon_ctx;
96 struct rmid_entry *entry;
97 u32 idx, cur_idx = 1;
98 bool rmid_dirty;
99 u64 val = 0;
100
101 arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, QOS_L3_OCCUP_EVENT_ID);
> 102 if (arch_mon_ctx < 0)
103 return;
104
105 /*
106 * Skip RMID 0 and start from RMID 1 and check all the RMIDs that
107 * are marked as busy for occupancy < threshold. If the occupancy
108 * is less than the threshold decrement the busy counter of the
109 * RMID and move it to the free list when the counter reaches 0.
110 */
111 for (;;) {
112 idx = find_next_bit(d->rmid_busy_llc, idx_limit, cur_idx);
113 if (idx >= idx_limit)
114 break;
115
116 entry = __rmid_entry(idx);
117 if (resctrl_arch_rmid_read(r, d, entry->closid, entry->rmid,
118 QOS_L3_OCCUP_EVENT_ID, &val,
119 arch_mon_ctx)) {
120 rmid_dirty = true;
121 } else {
122 rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
123 }
124
125 if (force_free || !rmid_dirty) {
126 clear_bit(idx, d->rmid_busy_llc);
127 if (!--entry->busy) {
128 rmid_limbo_count--;
129 list_add_tail(&entry->list, &rmid_free_lru);
130 }
131 }
132 cur_idx = idx + 1;
133 }
134
135 resctrl_arch_mon_ctx_free(r, QOS_L3_OCCUP_EVENT_ID, arch_mon_ctx);
136 }
137
138 bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d)
139 {
140 u32 idx_limit = resctrl_arch_system_num_rmid_idx();
141
142 return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
143 }
144
145 static struct rmid_entry *resctrl_find_free_rmid(u32 closid)
146 {
147 struct rmid_entry *itr;
148 u32 itr_idx, cmp_idx;
149
150 if (list_empty(&rmid_free_lru))
151 return rmid_limbo_count ? ERR_PTR(-EBUSY) : ERR_PTR(-ENOSPC);
152
153 list_for_each_entry(itr, &rmid_free_lru, list) {
154 /*
155 * get the index of this free rmid, and the index it would need
156 * to be if it were used with this closid.
157 * If the closid is irrelevant on this architecture, these will
158 * always be the same. Otherwise they will only match if this
159 * rmid can be used with this closid.
160 */
161 itr_idx = resctrl_arch_rmid_idx_encode(itr->closid, itr->rmid);
162 cmp_idx = resctrl_arch_rmid_idx_encode(closid, itr->rmid);
163
164 if (itr_idx == cmp_idx)
165 return itr;
166 }
167
168 return ERR_PTR(-ENOSPC);
169 }
170
171 /**
172 * resctrl_closid_is_dirty - Determine if clean rmid can be allocate for this
173 * closid.
174 * @closid: The closid that is being queried.
175 *
176 * MPAM's equivalent of rmid are per-closid, meaning a freshly allocate closid
177 * may not be able to allocate clean rmid. To avoid this the allocator will
178 * only return clean closid.
179 */
180 bool resctrl_closid_is_dirty(u32 closid)
181 {
182 struct rmid_entry *entry;
183 int i;
184
185 lockdep_assert_held(&rdtgroup_mutex);
186
187 if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
188 return false;
189
190 for (i = 0; i < resctrl_arch_system_num_rmid_idx(); i++) {
191 entry = &rmid_ptrs[i];
192 if (entry->closid != closid)
193 continue;
194
195 if (entry->busy)
196 return true;
197 }
198
199 return false;
200 }
201
202 /*
203 * As of now the RMIDs allocation is the same in each domain.
204 * However we keep track of which packages the RMIDs
205 * are used to optimize the limbo list management.
206 * The closid is ignored on x86.
207 */
208 int alloc_rmid(u32 closid)
209 {
210 struct rmid_entry *entry;
211
212 lockdep_assert_held(&rdtgroup_mutex);
213
214 entry = resctrl_find_free_rmid(closid);
215 if (!IS_ERR(entry)) {
216 list_del(&entry->list);
217 return entry->rmid;
218 }
219
220 return PTR_ERR(entry);
221 }
222
223 static void add_rmid_to_limbo(struct rmid_entry *entry)
224 {
225 struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
226 unsigned long arch_mon_ctx;
227 struct rdt_domain *d;
228 u64 val = 0;
229 u32 idx;
230 int err;
231
232 /* Walking r->domains, ensure it can't race with cpuhp */
233 lockdep_assert_cpus_held();
234
235 idx = resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid);
236
237 arch_mon_ctx = resctrl_arch_mon_ctx_alloc(r, QOS_L3_OCCUP_EVENT_ID);
> 238 if (arch_mon_ctx < 0)
239 return;
240
241 entry->busy = 0;
242 list_for_each_entry(d, &r->domains, list) {
243 err = resctrl_arch_rmid_read(r, d, entry->closid, entry->rmid,
244 QOS_L3_OCCUP_EVENT_ID, &val,
245 arch_mon_ctx);
246 if (err || val <= resctrl_rmid_realloc_threshold)
247 continue;
248
249 /*
250 * For the first limbo RMID in the domain,
251 * setup up the limbo worker.
252 */
253 if (!has_busy_rmid(r, d))
254 cqm_setup_limbo_handler(d, CQM_LIMBOCHECK_INTERVAL, -1);
255 set_bit(idx, d->rmid_busy_llc);
256 entry->busy++;
257 }
258 resctrl_arch_mon_ctx_free(r, QOS_L3_OCCUP_EVENT_ID, arch_mon_ctx);
259
260 if (entry->busy)
261 rmid_limbo_count++;
262 else
263 list_add_tail(&entry->list, &rmid_free_lru);
264 }
265

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

Attachment: .config.gz
Description: application/gzip