/** * struct bpf_cpumask - refcounted BPF cpumask wrapper structure * @cpumask: The actual cpumask embedded in the struct. * @usage: Object reference counter. When the refcount goes to 0, the * memory is released back to the BPF allocator, which provides * RCU safety. * * Note that we explicitly embed a cpumask_t rather than a cpumask_var_t. This * is done to avoid confusing the verifier due to the typedef of cpumask_var_t * changing depending on whether CONFIG_CPUMASK_OFFSTACK is defined or not. See * the details in <linux/cpumask.h>. The consequence is that this structure is * likely a bit larger than it needs to be when CONFIG_CPUMASK_OFFSTACK is * defined due to embedding the whole NR_CPUS-size bitmap, but the extra memory * overhead is minimal. For the more typical case of CONFIG_CPUMASK_OFFSTACK * not being defined, the structure is the same size regardless.
*/ struct bpf_cpumask {
cpumask_t cpumask;
refcount_t usage;
};
staticstruct bpf_mem_alloc bpf_cpumask_ma;
staticbool cpu_valid(u32 cpu)
{ return cpu < nr_cpu_ids;
}
__bpf_kfunc_start_defs();
/** * bpf_cpumask_create() - Create a mutable BPF cpumask. * * Allocates a cpumask that can be queried, mutated, acquired, and released by * a BPF program. The cpumask returned by this function must either be embedded * in a map as a kptr, or freed with bpf_cpumask_release(). * * bpf_cpumask_create() allocates memory using the BPF memory allocator, and * will not block. It may return NULL if no memory is available. * * Return: * * A pointer to a new struct bpf_cpumask instance on success. * * NULL if the BPF memory allocator is out of memory.
*/
__bpf_kfunc struct bpf_cpumask *bpf_cpumask_create(void)
{ struct bpf_cpumask *cpumask;
/* cpumask must be the first element so struct bpf_cpumask be cast to struct cpumask. */
BUILD_BUG_ON(offsetof(struct bpf_cpumask, cpumask) != 0);
cpumask = bpf_mem_cache_alloc(&bpf_cpumask_ma); if (!cpumask) return NULL;
/** * bpf_cpumask_acquire() - Acquire a reference to a BPF cpumask. * @cpumask: The BPF cpumask being acquired. The cpumask must be a trusted * pointer. * * Acquires a reference to a BPF cpumask. The cpumask returned by this function * must either be embedded in a map as a kptr, or freed with * bpf_cpumask_release(). * * Return: * * The struct bpf_cpumask pointer passed to the function. *
*/
__bpf_kfunc struct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask)
{
refcount_inc(&cpumask->usage); return cpumask;
}
/** * bpf_cpumask_release() - Release a previously acquired BPF cpumask. * @cpumask: The cpumask being released. * * Releases a previously acquired reference to a BPF cpumask. When the final * reference of the BPF cpumask has been released, it is subsequently freed in * an RCU callback in the BPF memory allocator.
*/
__bpf_kfunc void bpf_cpumask_release(struct bpf_cpumask *cpumask)
{ if (!refcount_dec_and_test(&cpumask->usage)) return;
/** * bpf_cpumask_first() - Get the index of the first nonzero bit in the cpumask. * @cpumask: The cpumask being queried. * * Find the index of the first nonzero bit of the cpumask. A struct bpf_cpumask * pointer may be safely passed to this function. * * Return: * * The index of the first nonzero bit in the struct cpumask.
*/
__bpf_kfunc u32 bpf_cpumask_first(conststruct cpumask *cpumask)
{ return cpumask_first(cpumask);
}
/** * bpf_cpumask_first_zero() - Get the index of the first unset bit in the * cpumask. * @cpumask: The cpumask being queried. * * Find the index of the first unset bit of the cpumask. A struct bpf_cpumask * pointer may be safely passed to this function. * * Return: * * The index of the first zero bit in the struct cpumask.
*/
__bpf_kfunc u32 bpf_cpumask_first_zero(conststruct cpumask *cpumask)
{ return cpumask_first_zero(cpumask);
}
/** * bpf_cpumask_first_and() - Return the index of the first nonzero bit from the * AND of two cpumasks. * @src1: The first cpumask. * @src2: The second cpumask. * * Find the index of the first nonzero bit of the AND of two cpumasks. * struct bpf_cpumask pointers may be safely passed to @src1 and @src2. * * Return: * * The index of the first bit that is nonzero in both cpumask instances.
*/
__bpf_kfunc u32 bpf_cpumask_first_and(conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_first_and(src1, src2);
}
/** * bpf_cpumask_set_cpu() - Set a bit for a CPU in a BPF cpumask. * @cpu: The CPU to be set in the cpumask. * @cpumask: The BPF cpumask in which a bit is being set.
*/
__bpf_kfunc void bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)
{ if (!cpu_valid(cpu)) return;
/** * bpf_cpumask_clear_cpu() - Clear a bit for a CPU in a BPF cpumask. * @cpu: The CPU to be cleared from the cpumask. * @cpumask: The BPF cpumask in which a bit is being cleared.
*/
__bpf_kfunc void bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)
{ if (!cpu_valid(cpu)) return;
/** * bpf_cpumask_test_cpu() - Test whether a CPU is set in a cpumask. * @cpu: The CPU being queried for. * @cpumask: The cpumask being queried for containing a CPU. * * Return: * * true - @cpu is set in the cpumask * * false - @cpu was not set in the cpumask, or @cpu is an invalid cpu.
*/
__bpf_kfunc bool bpf_cpumask_test_cpu(u32 cpu, conststruct cpumask *cpumask)
{ if (!cpu_valid(cpu)) returnfalse;
/** * bpf_cpumask_test_and_set_cpu() - Atomically test and set a CPU in a BPF cpumask. * @cpu: The CPU being set and queried for. * @cpumask: The BPF cpumask being set and queried for containing a CPU. * * Return: * * true - @cpu is set in the cpumask * * false - @cpu was not set in the cpumask, or @cpu is invalid.
*/
__bpf_kfunc bool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask)
{ if (!cpu_valid(cpu)) returnfalse;
/** * bpf_cpumask_test_and_clear_cpu() - Atomically test and clear a CPU in a BPF * cpumask. * @cpu: The CPU being cleared and queried for. * @cpumask: The BPF cpumask being cleared and queried for containing a CPU. * * Return: * * true - @cpu is set in the cpumask * * false - @cpu was not set in the cpumask, or @cpu is invalid.
*/
__bpf_kfunc bool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask)
{ if (!cpu_valid(cpu)) returnfalse;
/** * bpf_cpumask_setall() - Set all of the bits in a BPF cpumask. * @cpumask: The BPF cpumask having all of its bits set.
*/
__bpf_kfunc void bpf_cpumask_setall(struct bpf_cpumask *cpumask)
{
cpumask_setall((struct cpumask *)cpumask);
}
/** * bpf_cpumask_clear() - Clear all of the bits in a BPF cpumask. * @cpumask: The BPF cpumask being cleared.
*/
__bpf_kfunc void bpf_cpumask_clear(struct bpf_cpumask *cpumask)
{
cpumask_clear((struct cpumask *)cpumask);
}
/** * bpf_cpumask_and() - AND two cpumasks and store the result. * @dst: The BPF cpumask where the result is being stored. * @src1: The first input. * @src2: The second input. * * Return: * * true - @dst has at least one bit set following the operation * * false - @dst is empty following the operation * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc bool bpf_cpumask_and(struct bpf_cpumask *dst, conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_and((struct cpumask *)dst, src1, src2);
}
/** * bpf_cpumask_or() - OR two cpumasks and store the result. * @dst: The BPF cpumask where the result is being stored. * @src1: The first input. * @src2: The second input. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc void bpf_cpumask_or(struct bpf_cpumask *dst, conststruct cpumask *src1, conststruct cpumask *src2)
{
cpumask_or((struct cpumask *)dst, src1, src2);
}
/** * bpf_cpumask_xor() - XOR two cpumasks and store the result. * @dst: The BPF cpumask where the result is being stored. * @src1: The first input. * @src2: The second input. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc void bpf_cpumask_xor(struct bpf_cpumask *dst, conststruct cpumask *src1, conststruct cpumask *src2)
{
cpumask_xor((struct cpumask *)dst, src1, src2);
}
/** * bpf_cpumask_equal() - Check two cpumasks for equality. * @src1: The first input. * @src2: The second input. * * Return: * * true - @src1 and @src2 have the same bits set. * * false - @src1 and @src2 differ in at least one bit. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc bool bpf_cpumask_equal(conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_equal(src1, src2);
}
/** * bpf_cpumask_intersects() - Check two cpumasks for overlap. * @src1: The first input. * @src2: The second input. * * Return: * * true - @src1 and @src2 have at least one of the same bits set. * * false - @src1 and @src2 don't have any of the same bits set. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc bool bpf_cpumask_intersects(conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_intersects(src1, src2);
}
/** * bpf_cpumask_subset() - Check if a cpumask is a subset of another. * @src1: The first cpumask being checked as a subset. * @src2: The second cpumask being checked as a superset. * * Return: * * true - All of the bits of @src1 are set in @src2. * * false - At least one bit in @src1 is not set in @src2. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc bool bpf_cpumask_subset(conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_subset(src1, src2);
}
/** * bpf_cpumask_empty() - Check if a cpumask is empty. * @cpumask: The cpumask being checked. * * Return: * * true - None of the bits in @cpumask are set. * * false - At least one bit in @cpumask is set. * * A struct bpf_cpumask pointer may be safely passed to @cpumask.
*/
__bpf_kfunc bool bpf_cpumask_empty(conststruct cpumask *cpumask)
{ return cpumask_empty(cpumask);
}
/** * bpf_cpumask_full() - Check if a cpumask has all bits set. * @cpumask: The cpumask being checked. * * Return: * * true - All of the bits in @cpumask are set. * * false - At least one bit in @cpumask is cleared. * * A struct bpf_cpumask pointer may be safely passed to @cpumask.
*/
__bpf_kfunc bool bpf_cpumask_full(conststruct cpumask *cpumask)
{ return cpumask_full(cpumask);
}
/** * bpf_cpumask_copy() - Copy the contents of a cpumask into a BPF cpumask. * @dst: The BPF cpumask being copied into. * @src: The cpumask being copied. * * A struct bpf_cpumask pointer may be safely passed to @src.
*/
__bpf_kfunc void bpf_cpumask_copy(struct bpf_cpumask *dst, conststruct cpumask *src)
{
cpumask_copy((struct cpumask *)dst, src);
}
/** * bpf_cpumask_any_distribute() - Return a random set CPU from a cpumask. * @cpumask: The cpumask being queried. * * Return: * * A random set bit within [0, num_cpus) if at least one bit is set. * * >= num_cpus if no bit is set. * * A struct bpf_cpumask pointer may be safely passed to @src.
*/
__bpf_kfunc u32 bpf_cpumask_any_distribute(conststruct cpumask *cpumask)
{ return cpumask_any_distribute(cpumask);
}
/** * bpf_cpumask_any_and_distribute() - Return a random set CPU from the AND of * two cpumasks. * @src1: The first cpumask. * @src2: The second cpumask. * * Return: * * A random set bit within [0, num_cpus) from the AND of two cpumasks, if at * least one bit is set. * * >= num_cpus if no bit is set. * * struct bpf_cpumask pointers may be safely passed to @src1 and @src2.
*/
__bpf_kfunc u32 bpf_cpumask_any_and_distribute(conststruct cpumask *src1, conststruct cpumask *src2)
{ return cpumask_any_and_distribute(src1, src2);
}
/** * bpf_cpumask_weight() - Return the number of bits in @cpumask. * @cpumask: The cpumask being queried. * * Count the number of set bits in the given cpumask. * * Return: * * The number of bits set in the mask.
*/
__bpf_kfunc u32 bpf_cpumask_weight(conststruct cpumask *cpumask)
{ return cpumask_weight(cpumask);
}
/** * bpf_cpumask_populate() - Populate the CPU mask from the contents of * a BPF memory region. * * @cpumask: The cpumask being populated. * @src: The BPF memory holding the bit pattern. * @src__sz: Length of the BPF memory region in bytes. * * Return: * * 0 if the struct cpumask * instance was populated successfully. * * -EACCES if the memory region is too small to populate the cpumask. * * -EINVAL if the memory region is not aligned to the size of a long * and the architecture does not support efficient unaligned accesses.
*/
__bpf_kfunc int bpf_cpumask_populate(struct cpumask *cpumask, void *src, size_t src__sz)
{ unsignedlong source = (unsignedlong)src;
/* The memory region must be large enough to populate the entire CPU mask. */ if (src__sz < bitmap_size(nr_cpu_ids)) return -EACCES;
/* If avoiding unaligned accesses, the input region must be aligned to the nearest long. */ if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
!IS_ALIGNED(source, sizeof(long))) return -EINVAL;
ret = bpf_mem_alloc_init(&bpf_cpumask_ma, sizeof(struct bpf_cpumask), false);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &cpumask_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &cpumask_kfunc_set);
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &cpumask_kfunc_set); return ret ?: register_btf_id_dtor_kfuncs(cpumask_dtors,
ARRAY_SIZE(cpumask_dtors),
THIS_MODULE);
}
late_initcall(cpumask_kfunc_init);
Messung V0.5
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.