162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#ifndef _CPUMASK_COMMON_H
562306a36Sopenharmony_ci#define _CPUMASK_COMMON_H
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include "errno.h"
862306a36Sopenharmony_ci#include <stdbool.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciint err;
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
1362306a36Sopenharmony_ciprivate(MASK) static struct bpf_cpumask __kptr * global_mask;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct __cpumask_map_value {
1662306a36Sopenharmony_ci	struct bpf_cpumask __kptr * cpumask;
1762306a36Sopenharmony_ci};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistruct array_map {
2062306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_ARRAY);
2162306a36Sopenharmony_ci	__type(key, int);
2262306a36Sopenharmony_ci	__type(value, struct __cpumask_map_value);
2362306a36Sopenharmony_ci	__uint(max_entries, 1);
2462306a36Sopenharmony_ci} __cpumask_map SEC(".maps");
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistruct bpf_cpumask *bpf_cpumask_create(void) __ksym;
2762306a36Sopenharmony_civoid bpf_cpumask_release(struct bpf_cpumask *cpumask) __ksym;
2862306a36Sopenharmony_cistruct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask) __ksym;
2962306a36Sopenharmony_ciu32 bpf_cpumask_first(const struct cpumask *cpumask) __ksym;
3062306a36Sopenharmony_ciu32 bpf_cpumask_first_zero(const struct cpumask *cpumask) __ksym;
3162306a36Sopenharmony_ciu32 bpf_cpumask_first_and(const struct cpumask *src1,
3262306a36Sopenharmony_ci			  const struct cpumask *src2) __ksym;
3362306a36Sopenharmony_civoid bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym;
3462306a36Sopenharmony_civoid bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym;
3562306a36Sopenharmony_cibool bpf_cpumask_test_cpu(u32 cpu, const struct cpumask *cpumask) __ksym;
3662306a36Sopenharmony_cibool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym;
3762306a36Sopenharmony_cibool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym;
3862306a36Sopenharmony_civoid bpf_cpumask_setall(struct bpf_cpumask *cpumask) __ksym;
3962306a36Sopenharmony_civoid bpf_cpumask_clear(struct bpf_cpumask *cpumask) __ksym;
4062306a36Sopenharmony_cibool bpf_cpumask_and(struct bpf_cpumask *cpumask,
4162306a36Sopenharmony_ci		     const struct cpumask *src1,
4262306a36Sopenharmony_ci		     const struct cpumask *src2) __ksym;
4362306a36Sopenharmony_civoid bpf_cpumask_or(struct bpf_cpumask *cpumask,
4462306a36Sopenharmony_ci		    const struct cpumask *src1,
4562306a36Sopenharmony_ci		    const struct cpumask *src2) __ksym;
4662306a36Sopenharmony_civoid bpf_cpumask_xor(struct bpf_cpumask *cpumask,
4762306a36Sopenharmony_ci		     const struct cpumask *src1,
4862306a36Sopenharmony_ci		     const struct cpumask *src2) __ksym;
4962306a36Sopenharmony_cibool bpf_cpumask_equal(const struct cpumask *src1, const struct cpumask *src2) __ksym;
5062306a36Sopenharmony_cibool bpf_cpumask_intersects(const struct cpumask *src1, const struct cpumask *src2) __ksym;
5162306a36Sopenharmony_cibool bpf_cpumask_subset(const struct cpumask *src1, const struct cpumask *src2) __ksym;
5262306a36Sopenharmony_cibool bpf_cpumask_empty(const struct cpumask *cpumask) __ksym;
5362306a36Sopenharmony_cibool bpf_cpumask_full(const struct cpumask *cpumask) __ksym;
5462306a36Sopenharmony_civoid bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym;
5562306a36Sopenharmony_ciu32 bpf_cpumask_any_distribute(const struct cpumask *src) __ksym;
5662306a36Sopenharmony_ciu32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, const struct cpumask *src2) __ksym;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_civoid bpf_rcu_read_lock(void) __ksym;
5962306a36Sopenharmony_civoid bpf_rcu_read_unlock(void) __ksym;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic inline const struct cpumask *cast(struct bpf_cpumask *cpumask)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	return (const struct cpumask *)cpumask;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline struct bpf_cpumask *create_cpumask(void)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	struct bpf_cpumask *cpumask;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	cpumask = bpf_cpumask_create();
7162306a36Sopenharmony_ci	if (!cpumask) {
7262306a36Sopenharmony_ci		err = 1;
7362306a36Sopenharmony_ci		return NULL;
7462306a36Sopenharmony_ci	}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	if (!bpf_cpumask_empty(cast(cpumask))) {
7762306a36Sopenharmony_ci		err = 2;
7862306a36Sopenharmony_ci		bpf_cpumask_release(cpumask);
7962306a36Sopenharmony_ci		return NULL;
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	return cpumask;
8362306a36Sopenharmony_ci}
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic inline struct __cpumask_map_value *cpumask_map_value_lookup(void)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	u32 key = 0;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	return bpf_map_lookup_elem(&__cpumask_map, &key);
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic inline int cpumask_map_insert(struct bpf_cpumask *mask)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	struct __cpumask_map_value local, *v;
9562306a36Sopenharmony_ci	long status;
9662306a36Sopenharmony_ci	struct bpf_cpumask *old;
9762306a36Sopenharmony_ci	u32 key = 0;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	local.cpumask = NULL;
10062306a36Sopenharmony_ci	status = bpf_map_update_elem(&__cpumask_map, &key, &local, 0);
10162306a36Sopenharmony_ci	if (status) {
10262306a36Sopenharmony_ci		bpf_cpumask_release(mask);
10362306a36Sopenharmony_ci		return status;
10462306a36Sopenharmony_ci	}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	v = bpf_map_lookup_elem(&__cpumask_map, &key);
10762306a36Sopenharmony_ci	if (!v) {
10862306a36Sopenharmony_ci		bpf_cpumask_release(mask);
10962306a36Sopenharmony_ci		return -ENOENT;
11062306a36Sopenharmony_ci	}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	old = bpf_kptr_xchg(&v->cpumask, mask);
11362306a36Sopenharmony_ci	if (old) {
11462306a36Sopenharmony_ci		bpf_cpumask_release(old);
11562306a36Sopenharmony_ci		return -EEXIST;
11662306a36Sopenharmony_ci	}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	return 0;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci#endif /* _CPUMASK_COMMON_H */
122