xref: /openbmc/linux/kernel/bpf/cpumask.c (revision 5ad1ab30)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2023 Meta, Inc */
3 #include <linux/bpf.h>
4 #include <linux/bpf_mem_alloc.h>
5 #include <linux/btf.h>
6 #include <linux/btf_ids.h>
7 #include <linux/cpumask.h>
8 
9 /**
10  * struct bpf_cpumask - refcounted BPF cpumask wrapper structure
11  * @cpumask:	The actual cpumask embedded in the struct.
12  * @rcu:	The RCU head used to free the cpumask with RCU safety.
13  * @usage:	Object reference counter. When the refcount goes to 0, the
14  *		memory is released back to the BPF allocator, which provides
15  *		RCU safety.
16  *
17  * Note that we explicitly embed a cpumask_t rather than a cpumask_var_t.  This
18  * is done to avoid confusing the verifier due to the typedef of cpumask_var_t
19  * changing depending on whether CONFIG_CPUMASK_OFFSTACK is defined or not. See
20  * the details in <linux/cpumask.h>. The consequence is that this structure is
21  * likely a bit larger than it needs to be when CONFIG_CPUMASK_OFFSTACK is
22  * defined due to embedding the whole NR_CPUS-size bitmap, but the extra memory
23  * overhead is minimal. For the more typical case of CONFIG_CPUMASK_OFFSTACK
24  * not being defined, the structure is the same size regardless.
25  */
26 struct bpf_cpumask {
27 	cpumask_t cpumask;
28 	struct rcu_head rcu;
29 	refcount_t usage;
30 };
31 
32 static struct bpf_mem_alloc bpf_cpumask_ma;
33 
34 static bool cpu_valid(u32 cpu)
35 {
36 	return cpu < nr_cpu_ids;
37 }
38 
39 __diag_push();
40 __diag_ignore_all("-Wmissing-prototypes",
41 		  "Global kfuncs as their definitions will be in BTF");
42 
43 /**
44  * bpf_cpumask_create() - Create a mutable BPF cpumask.
45  *
46  * Allocates a cpumask that can be queried, mutated, acquired, and released by
47  * a BPF program. The cpumask returned by this function must either be embedded
48  * in a map as a kptr, or freed with bpf_cpumask_release().
49  *
50  * bpf_cpumask_create() allocates memory using the BPF memory allocator, and
51  * will not block. It may return NULL if no memory is available.
52  */
53 __bpf_kfunc struct bpf_cpumask *bpf_cpumask_create(void)
54 {
55 	struct bpf_cpumask *cpumask;
56 
57 	/* cpumask must be the first element so struct bpf_cpumask be cast to struct cpumask. */
58 	BUILD_BUG_ON(offsetof(struct bpf_cpumask, cpumask) != 0);
59 
60 	cpumask = bpf_mem_cache_alloc(&bpf_cpumask_ma);
61 	if (!cpumask)
62 		return NULL;
63 
64 	memset(cpumask, 0, sizeof(*cpumask));
65 	refcount_set(&cpumask->usage, 1);
66 
67 	return cpumask;
68 }
69 
70 /**
71  * bpf_cpumask_acquire() - Acquire a reference to a BPF cpumask.
72  * @cpumask: The BPF cpumask being acquired. The cpumask must be a trusted
73  *	     pointer.
74  *
75  * Acquires a reference to a BPF cpumask. The cpumask returned by this function
76  * must either be embedded in a map as a kptr, or freed with
77  * bpf_cpumask_release().
78  */
79 __bpf_kfunc struct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask)
80 {
81 	refcount_inc(&cpumask->usage);
82 	return cpumask;
83 }
84 
85 static void cpumask_free_cb(struct rcu_head *head)
86 {
87 	struct bpf_cpumask *cpumask;
88 
89 	cpumask = container_of(head, struct bpf_cpumask, rcu);
90 	migrate_disable();
91 	bpf_mem_cache_free(&bpf_cpumask_ma, cpumask);
92 	migrate_enable();
93 }
94 
95 /**
96  * bpf_cpumask_release() - Release a previously acquired BPF cpumask.
97  * @cpumask: The cpumask being released.
98  *
99  * Releases a previously acquired reference to a BPF cpumask. When the final
100  * reference of the BPF cpumask has been released, it is subsequently freed in
101  * an RCU callback in the BPF memory allocator.
102  */
103 __bpf_kfunc void bpf_cpumask_release(struct bpf_cpumask *cpumask)
104 {
105 	if (refcount_dec_and_test(&cpumask->usage))
106 		call_rcu(&cpumask->rcu, cpumask_free_cb);
107 }
108 
109 /**
110  * bpf_cpumask_first() - Get the index of the first nonzero bit in the cpumask.
111  * @cpumask: The cpumask being queried.
112  *
113  * Find the index of the first nonzero bit of the cpumask. A struct bpf_cpumask
114  * pointer may be safely passed to this function.
115  */
116 __bpf_kfunc u32 bpf_cpumask_first(const struct cpumask *cpumask)
117 {
118 	return cpumask_first(cpumask);
119 }
120 
121 /**
122  * bpf_cpumask_first_zero() - Get the index of the first unset bit in the
123  *			      cpumask.
124  * @cpumask: The cpumask being queried.
125  *
126  * Find the index of the first unset bit of the cpumask. A struct bpf_cpumask
127  * pointer may be safely passed to this function.
128  */
129 __bpf_kfunc u32 bpf_cpumask_first_zero(const struct cpumask *cpumask)
130 {
131 	return cpumask_first_zero(cpumask);
132 }
133 
134 /**
135  * bpf_cpumask_first_and() - Return the index of the first nonzero bit from the
136  *			     AND of two cpumasks.
137  * @src1: The first cpumask.
138  * @src2: The second cpumask.
139  *
140  * Find the index of the first nonzero bit of the AND of two cpumasks.
141  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
142  */
143 __bpf_kfunc u32 bpf_cpumask_first_and(const struct cpumask *src1,
144 				      const struct cpumask *src2)
145 {
146 	return cpumask_first_and(src1, src2);
147 }
148 
149 /**
150  * bpf_cpumask_set_cpu() - Set a bit for a CPU in a BPF cpumask.
151  * @cpu: The CPU to be set in the cpumask.
152  * @cpumask: The BPF cpumask in which a bit is being set.
153  */
154 __bpf_kfunc void bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)
155 {
156 	if (!cpu_valid(cpu))
157 		return;
158 
159 	cpumask_set_cpu(cpu, (struct cpumask *)cpumask);
160 }
161 
162 /**
163  * bpf_cpumask_clear_cpu() - Clear a bit for a CPU in a BPF cpumask.
164  * @cpu: The CPU to be cleared from the cpumask.
165  * @cpumask: The BPF cpumask in which a bit is being cleared.
166  */
167 __bpf_kfunc void bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)
168 {
169 	if (!cpu_valid(cpu))
170 		return;
171 
172 	cpumask_clear_cpu(cpu, (struct cpumask *)cpumask);
173 }
174 
175 /**
176  * bpf_cpumask_test_cpu() - Test whether a CPU is set in a cpumask.
177  * @cpu: The CPU being queried for.
178  * @cpumask: The cpumask being queried for containing a CPU.
179  *
180  * Return:
181  * * true  - @cpu is set in the cpumask
182  * * false - @cpu was not set in the cpumask, or @cpu is an invalid cpu.
183  */
184 __bpf_kfunc bool bpf_cpumask_test_cpu(u32 cpu, const struct cpumask *cpumask)
185 {
186 	if (!cpu_valid(cpu))
187 		return false;
188 
189 	return cpumask_test_cpu(cpu, (struct cpumask *)cpumask);
190 }
191 
192 /**
193  * bpf_cpumask_test_and_set_cpu() - Atomically test and set a CPU in a BPF cpumask.
194  * @cpu: The CPU being set and queried for.
195  * @cpumask: The BPF cpumask being set and queried for containing a CPU.
196  *
197  * Return:
198  * * true  - @cpu is set in the cpumask
199  * * false - @cpu was not set in the cpumask, or @cpu is invalid.
200  */
201 __bpf_kfunc bool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)
202 {
203 	if (!cpu_valid(cpu))
204 		return false;
205 
206 	return cpumask_test_and_set_cpu(cpu, (struct cpumask *)cpumask);
207 }
208 
209 /**
210  * bpf_cpumask_test_and_clear_cpu() - Atomically test and clear a CPU in a BPF
211  *				      cpumask.
212  * @cpu: The CPU being cleared and queried for.
213  * @cpumask: The BPF cpumask being cleared and queried for containing a CPU.
214  *
215  * Return:
216  * * true  - @cpu is set in the cpumask
217  * * false - @cpu was not set in the cpumask, or @cpu is invalid.
218  */
219 __bpf_kfunc bool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)
220 {
221 	if (!cpu_valid(cpu))
222 		return false;
223 
224 	return cpumask_test_and_clear_cpu(cpu, (struct cpumask *)cpumask);
225 }
226 
227 /**
228  * bpf_cpumask_setall() - Set all of the bits in a BPF cpumask.
229  * @cpumask: The BPF cpumask having all of its bits set.
230  */
231 __bpf_kfunc void bpf_cpumask_setall(struct bpf_cpumask *cpumask)
232 {
233 	cpumask_setall((struct cpumask *)cpumask);
234 }
235 
236 /**
237  * bpf_cpumask_clear() - Clear all of the bits in a BPF cpumask.
238  * @cpumask: The BPF cpumask being cleared.
239  */
240 __bpf_kfunc void bpf_cpumask_clear(struct bpf_cpumask *cpumask)
241 {
242 	cpumask_clear((struct cpumask *)cpumask);
243 }
244 
245 /**
246  * bpf_cpumask_and() - AND two cpumasks and store the result.
247  * @dst: The BPF cpumask where the result is being stored.
248  * @src1: The first input.
249  * @src2: The second input.
250  *
251  * Return:
252  * * true  - @dst has at least one bit set following the operation
253  * * false - @dst is empty following the operation
254  *
255  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
256  */
257 __bpf_kfunc bool bpf_cpumask_and(struct bpf_cpumask *dst,
258 				 const struct cpumask *src1,
259 				 const struct cpumask *src2)
260 {
261 	return cpumask_and((struct cpumask *)dst, src1, src2);
262 }
263 
264 /**
265  * bpf_cpumask_or() - OR two cpumasks and store the result.
266  * @dst: The BPF cpumask where the result is being stored.
267  * @src1: The first input.
268  * @src2: The second input.
269  *
270  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
271  */
272 __bpf_kfunc void bpf_cpumask_or(struct bpf_cpumask *dst,
273 				const struct cpumask *src1,
274 				const struct cpumask *src2)
275 {
276 	cpumask_or((struct cpumask *)dst, src1, src2);
277 }
278 
279 /**
280  * bpf_cpumask_xor() - XOR two cpumasks and store the result.
281  * @dst: The BPF cpumask where the result is being stored.
282  * @src1: The first input.
283  * @src2: The second input.
284  *
285  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
286  */
287 __bpf_kfunc void bpf_cpumask_xor(struct bpf_cpumask *dst,
288 				 const struct cpumask *src1,
289 				 const struct cpumask *src2)
290 {
291 	cpumask_xor((struct cpumask *)dst, src1, src2);
292 }
293 
294 /**
295  * bpf_cpumask_equal() - Check two cpumasks for equality.
296  * @src1: The first input.
297  * @src2: The second input.
298  *
299  * Return:
300  * * true   - @src1 and @src2 have the same bits set.
301  * * false  - @src1 and @src2 differ in at least one bit.
302  *
303  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
304  */
305 __bpf_kfunc bool bpf_cpumask_equal(const struct cpumask *src1, const struct cpumask *src2)
306 {
307 	return cpumask_equal(src1, src2);
308 }
309 
310 /**
311  * bpf_cpumask_intersects() - Check two cpumasks for overlap.
312  * @src1: The first input.
313  * @src2: The second input.
314  *
315  * Return:
316  * * true   - @src1 and @src2 have at least one of the same bits set.
317  * * false  - @src1 and @src2 don't have any of the same bits set.
318  *
319  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
320  */
321 __bpf_kfunc bool bpf_cpumask_intersects(const struct cpumask *src1, const struct cpumask *src2)
322 {
323 	return cpumask_intersects(src1, src2);
324 }
325 
326 /**
327  * bpf_cpumask_subset() - Check if a cpumask is a subset of another.
328  * @src1: The first cpumask being checked as a subset.
329  * @src2: The second cpumask being checked as a superset.
330  *
331  * Return:
332  * * true   - All of the bits of @src1 are set in @src2.
333  * * false  - At least one bit in @src1 is not set in @src2.
334  *
335  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
336  */
337 __bpf_kfunc bool bpf_cpumask_subset(const struct cpumask *src1, const struct cpumask *src2)
338 {
339 	return cpumask_subset(src1, src2);
340 }
341 
342 /**
343  * bpf_cpumask_empty() - Check if a cpumask is empty.
344  * @cpumask: The cpumask being checked.
345  *
346  * Return:
347  * * true   - None of the bits in @cpumask are set.
348  * * false  - At least one bit in @cpumask is set.
349  *
350  * A struct bpf_cpumask pointer may be safely passed to @cpumask.
351  */
352 __bpf_kfunc bool bpf_cpumask_empty(const struct cpumask *cpumask)
353 {
354 	return cpumask_empty(cpumask);
355 }
356 
357 /**
358  * bpf_cpumask_full() - Check if a cpumask has all bits set.
359  * @cpumask: The cpumask being checked.
360  *
361  * Return:
362  * * true   - All of the bits in @cpumask are set.
363  * * false  - At least one bit in @cpumask is cleared.
364  *
365  * A struct bpf_cpumask pointer may be safely passed to @cpumask.
366  */
367 __bpf_kfunc bool bpf_cpumask_full(const struct cpumask *cpumask)
368 {
369 	return cpumask_full(cpumask);
370 }
371 
372 /**
373  * bpf_cpumask_copy() - Copy the contents of a cpumask into a BPF cpumask.
374  * @dst: The BPF cpumask being copied into.
375  * @src: The cpumask being copied.
376  *
377  * A struct bpf_cpumask pointer may be safely passed to @src.
378  */
379 __bpf_kfunc void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src)
380 {
381 	cpumask_copy((struct cpumask *)dst, src);
382 }
383 
384 /**
385  * bpf_cpumask_any_distribute() - Return a random set CPU from a cpumask.
386  * @cpumask: The cpumask being queried.
387  *
388  * Return:
389  * * A random set bit within [0, num_cpus) if at least one bit is set.
390  * * >= num_cpus if no bit is set.
391  *
392  * A struct bpf_cpumask pointer may be safely passed to @src.
393  */
394 __bpf_kfunc u32 bpf_cpumask_any_distribute(const struct cpumask *cpumask)
395 {
396 	return cpumask_any_distribute(cpumask);
397 }
398 
399 /**
400  * bpf_cpumask_any_and_distribute() - Return a random set CPU from the AND of
401  *				      two cpumasks.
402  * @src1: The first cpumask.
403  * @src2: The second cpumask.
404  *
405  * Return:
406  * * A random set bit within [0, num_cpus) from the AND of two cpumasks, if at
407  *   least one bit is set.
408  * * >= num_cpus if no bit is set.
409  *
410  * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
411  */
412 __bpf_kfunc u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1,
413 					       const struct cpumask *src2)
414 {
415 	return cpumask_any_and_distribute(src1, src2);
416 }
417 
418 __diag_pop();
419 
420 BTF_SET8_START(cpumask_kfunc_btf_ids)
421 BTF_ID_FLAGS(func, bpf_cpumask_create, KF_ACQUIRE | KF_RET_NULL)
422 BTF_ID_FLAGS(func, bpf_cpumask_release, KF_RELEASE)
423 BTF_ID_FLAGS(func, bpf_cpumask_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS)
424 BTF_ID_FLAGS(func, bpf_cpumask_first, KF_RCU)
425 BTF_ID_FLAGS(func, bpf_cpumask_first_zero, KF_RCU)
426 BTF_ID_FLAGS(func, bpf_cpumask_first_and, KF_RCU)
427 BTF_ID_FLAGS(func, bpf_cpumask_set_cpu, KF_RCU)
428 BTF_ID_FLAGS(func, bpf_cpumask_clear_cpu, KF_RCU)
429 BTF_ID_FLAGS(func, bpf_cpumask_test_cpu, KF_RCU)
430 BTF_ID_FLAGS(func, bpf_cpumask_test_and_set_cpu, KF_RCU)
431 BTF_ID_FLAGS(func, bpf_cpumask_test_and_clear_cpu, KF_RCU)
432 BTF_ID_FLAGS(func, bpf_cpumask_setall, KF_RCU)
433 BTF_ID_FLAGS(func, bpf_cpumask_clear, KF_RCU)
434 BTF_ID_FLAGS(func, bpf_cpumask_and, KF_RCU)
435 BTF_ID_FLAGS(func, bpf_cpumask_or, KF_RCU)
436 BTF_ID_FLAGS(func, bpf_cpumask_xor, KF_RCU)
437 BTF_ID_FLAGS(func, bpf_cpumask_equal, KF_RCU)
438 BTF_ID_FLAGS(func, bpf_cpumask_intersects, KF_RCU)
439 BTF_ID_FLAGS(func, bpf_cpumask_subset, KF_RCU)
440 BTF_ID_FLAGS(func, bpf_cpumask_empty, KF_RCU)
441 BTF_ID_FLAGS(func, bpf_cpumask_full, KF_RCU)
442 BTF_ID_FLAGS(func, bpf_cpumask_copy, KF_RCU)
443 BTF_ID_FLAGS(func, bpf_cpumask_any_distribute, KF_RCU)
444 BTF_ID_FLAGS(func, bpf_cpumask_any_and_distribute, KF_RCU)
445 BTF_SET8_END(cpumask_kfunc_btf_ids)
446 
447 static const struct btf_kfunc_id_set cpumask_kfunc_set = {
448 	.owner = THIS_MODULE,
449 	.set   = &cpumask_kfunc_btf_ids,
450 };
451 
452 BTF_ID_LIST(cpumask_dtor_ids)
453 BTF_ID(struct, bpf_cpumask)
454 BTF_ID(func, bpf_cpumask_release)
455 
456 static int __init cpumask_kfunc_init(void)
457 {
458 	int ret;
459 	const struct btf_id_dtor_kfunc cpumask_dtors[] = {
460 		{
461 			.btf_id	      = cpumask_dtor_ids[0],
462 			.kfunc_btf_id = cpumask_dtor_ids[1]
463 		},
464 	};
465 
466 	ret = bpf_mem_alloc_init(&bpf_cpumask_ma, sizeof(struct bpf_cpumask), false);
467 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &cpumask_kfunc_set);
468 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &cpumask_kfunc_set);
469 	return  ret ?: register_btf_id_dtor_kfuncs(cpumask_dtors,
470 						   ARRAY_SIZE(cpumask_dtors),
471 						   THIS_MODULE);
472 }
473 
474 late_initcall(cpumask_kfunc_init);
475