2023-12-07 21:09:07

by David Vernet

[permalink] [raw]
Subject: [PATCH bpf-next 0/2] Add new bpf_cpumask_weight() kfunc

It can be useful to query how many bits are set in a cpumask. For
example, if you want to perform special logic for the last remaining
core that's set in a mask. This logic is already exposed through the
main kernel's cpumask header as cpumask_weight(), so it would be useful
to add a new bpf_cpumask_weight() kfunc which wraps it and does the
same.

This patch series was built and tested on top of commit 2146f7fe6e02
("Merge branch 'allocate-bpf-trampoline-on-bpf_prog_pack'").

David Vernet (2):
bpf: Add bpf_cpumask_weight() kfunc
selftests/bpf: Add test for bpf_cpumask_weight() kfunc

Documentation/bpf/cpumasks.rst | 2 +-
kernel/bpf/cpumask.c | 12 ++++++
.../selftests/bpf/prog_tests/cpumask.c | 1 +
.../selftests/bpf/progs/cpumask_common.h | 1 +
.../selftests/bpf/progs/cpumask_success.c | 43 +++++++++++++++++++
5 files changed, 58 insertions(+), 1 deletion(-)

--
2.42.1


2023-12-07 21:09:10

by David Vernet

[permalink] [raw]
Subject: [PATCH bpf-next 1/2] bpf: Add bpf_cpumask_weight() kfunc

It can be useful to query how many bits are set in a cpumask. For
example, if you want to perform special logic for the last remaining
core that's set in a mask. Let's therefore add a new
bpf_cpumask_weight() kfunc which checks how many bits are set in a mask.

Signed-off-by: David Vernet <[email protected]>
---
Documentation/bpf/cpumasks.rst | 2 +-
kernel/bpf/cpumask.c | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/Documentation/bpf/cpumasks.rst b/Documentation/bpf/cpumasks.rst
index a22b6ad105fb..b5d47a04da5d 100644
--- a/Documentation/bpf/cpumasks.rst
+++ b/Documentation/bpf/cpumasks.rst
@@ -352,7 +352,7 @@ can be used to query the contents of cpumasks.

.. kernel-doc:: kernel/bpf/cpumask.c
:identifiers: bpf_cpumask_first bpf_cpumask_first_zero bpf_cpumask_first_and
- bpf_cpumask_test_cpu
+ bpf_cpumask_test_cpu bpf_cpumask_weight

.. kernel-doc:: kernel/bpf/cpumask.c
:identifiers: bpf_cpumask_equal bpf_cpumask_intersects bpf_cpumask_subset
diff --git a/kernel/bpf/cpumask.c b/kernel/bpf/cpumask.c
index e01c741e54e7..7499b7d8c06f 100644
--- a/kernel/bpf/cpumask.c
+++ b/kernel/bpf/cpumask.c
@@ -405,6 +405,17 @@ __bpf_kfunc u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1,
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.
+ */
+__bpf_kfunc u32 bpf_cpumask_weight(const struct cpumask *cpumask)
+{
+ return cpumask_weight(cpumask);
+}
+
__bpf_kfunc_end_defs();

BTF_SET8_START(cpumask_kfunc_btf_ids)
@@ -432,6 +443,7 @@ BTF_ID_FLAGS(func, bpf_cpumask_full, KF_RCU)
BTF_ID_FLAGS(func, bpf_cpumask_copy, KF_RCU)
BTF_ID_FLAGS(func, bpf_cpumask_any_distribute, KF_RCU)
BTF_ID_FLAGS(func, bpf_cpumask_any_and_distribute, KF_RCU)
+BTF_ID_FLAGS(func, bpf_cpumask_weight, KF_RCU)
BTF_SET8_END(cpumask_kfunc_btf_ids)

static const struct btf_kfunc_id_set cpumask_kfunc_set = {
--
2.42.1

2023-12-07 21:09:23

by David Vernet

[permalink] [raw]
Subject: [PATCH bpf-next 2/2] selftests/bpf: Add test for bpf_cpumask_weight() kfunc

The new bpf_cpumask_weight() kfunc can be used to count the number of
bits that are set in a struct cpumask* kptr. Let's add a selftest to
verify its behavior.

Signed-off-by: David Vernet <[email protected]>
---
.../selftests/bpf/prog_tests/cpumask.c | 1 +
.../selftests/bpf/progs/cpumask_common.h | 1 +
.../selftests/bpf/progs/cpumask_success.c | 43 +++++++++++++++++++
3 files changed, 45 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/cpumask.c b/tools/testing/selftests/bpf/prog_tests/cpumask.c
index 756ea8b590b6..c2e886399e3c 100644
--- a/tools/testing/selftests/bpf/prog_tests/cpumask.c
+++ b/tools/testing/selftests/bpf/prog_tests/cpumask.c
@@ -18,6 +18,7 @@ static const char * const cpumask_success_testcases[] = {
"test_insert_leave",
"test_insert_remove_release",
"test_global_mask_rcu",
+ "test_cpumask_weight",
};

static void verify_success(const char *prog_name)
diff --git a/tools/testing/selftests/bpf/progs/cpumask_common.h b/tools/testing/selftests/bpf/progs/cpumask_common.h
index b15c588ace15..0cd4aebb97cf 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_common.h
+++ b/tools/testing/selftests/bpf/progs/cpumask_common.h
@@ -54,6 +54,7 @@ bool bpf_cpumask_full(const struct cpumask *cpumask) __ksym;
void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym;
u32 bpf_cpumask_any_distribute(const struct cpumask *src) __ksym;
u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, const struct cpumask *src2) __ksym;
+u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym;

void bpf_rcu_read_lock(void) __ksym;
void bpf_rcu_read_unlock(void) __ksym;
diff --git a/tools/testing/selftests/bpf/progs/cpumask_success.c b/tools/testing/selftests/bpf/progs/cpumask_success.c
index 674a63424dee..fc3666edf456 100644
--- a/tools/testing/selftests/bpf/progs/cpumask_success.c
+++ b/tools/testing/selftests/bpf/progs/cpumask_success.c
@@ -460,6 +460,49 @@ int BPF_PROG(test_global_mask_rcu, struct task_struct *task, u64 clone_flags)
return 0;
}

+SEC("tp_btf/task_newtask")
+int BPF_PROG(test_cpumask_weight, struct task_struct *task, u64 clone_flags)
+{
+ struct bpf_cpumask *local;
+
+ if (!is_test_task())
+ return 0;
+
+ local = create_cpumask();
+ if (!local)
+ return 0;
+
+ if (bpf_cpumask_weight(cast(local)) != 0) {
+ err = 3;
+ goto out;
+ }
+
+ bpf_cpumask_set_cpu(0, local);
+ if (bpf_cpumask_weight(cast(local)) != 1) {
+ err = 4;
+ goto out;
+ }
+
+ /*
+ * Make sure that adding additional CPUs changes the weight. Test to
+ * see whether the CPU was set to account for running on UP machines.
+ */
+ bpf_cpumask_set_cpu(1, local);
+ if (bpf_cpumask_test_cpu(1, cast(local)) && bpf_cpumask_weight(cast(local)) != 2) {
+ err = 5;
+ goto out;
+ }
+
+ bpf_cpumask_clear(local);
+ if (bpf_cpumask_weight(cast(local)) != 0) {
+ err = 6;
+ goto out;
+ }
+out:
+ bpf_cpumask_release(local);
+ return 0;
+}
+
SEC("tp_btf/task_newtask")
__success
int BPF_PROG(test_refcount_null_tracking, struct task_struct *task, u64 clone_flags)
--
2.42.1

2023-12-08 04:38:08

by Yonghong Song

[permalink] [raw]
Subject: Re: [PATCH bpf-next 1/2] bpf: Add bpf_cpumask_weight() kfunc


On 12/7/23 1:08 PM, David Vernet wrote:
> It can be useful to query how many bits are set in a cpumask. For
> example, if you want to perform special logic for the last remaining
> core that's set in a mask. Let's therefore add a new
> bpf_cpumask_weight() kfunc which checks how many bits are set in a mask.
>
> Signed-off-by: David Vernet <[email protected]>

Acked-by: Yonghong Song <[email protected]>

2023-12-08 04:41:07

by Yonghong Song

[permalink] [raw]
Subject: Re: [PATCH bpf-next 2/2] selftests/bpf: Add test for bpf_cpumask_weight() kfunc


On 12/7/23 1:08 PM, David Vernet wrote:
> The new bpf_cpumask_weight() kfunc can be used to count the number of
> bits that are set in a struct cpumask* kptr. Let's add a selftest to
> verify its behavior.
>
> Signed-off-by: David Vernet <[email protected]>

Acked-by: Yonghong Song <[email protected]>

2023-12-10 05:41:13

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH bpf-next 0/2] Add new bpf_cpumask_weight() kfunc

Hello:

This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <[email protected]>:

On Thu, 7 Dec 2023 15:08:41 -0600 you wrote:
> It can be useful to query how many bits are set in a cpumask. For
> example, if you want to perform special logic for the last remaining
> core that's set in a mask. This logic is already exposed through the
> main kernel's cpumask header as cpumask_weight(), so it would be useful
> to add a new bpf_cpumask_weight() kfunc which wraps it and does the
> same.
>
> [...]

Here is the summary with links:
- [bpf-next,1/2] bpf: Add bpf_cpumask_weight() kfunc
https://git.kernel.org/bpf/bpf-next/c/a6de18f310a5
- [bpf-next,2/2] selftests/bpf: Add test for bpf_cpumask_weight() kfunc
https://git.kernel.org/bpf/bpf-next/c/88f6047191e6

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html