Commit fa96b242 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Alexei Starovoitov
Browse files

btf: Add a new kfunc flag which allows to mark a function to be sleepable



This allows to declare a kfunc as sleepable and prevents its use in
a non sleepable program.

Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Co-developed-by: default avatarYosry Ahmed <yosryahmed@google.com>
Signed-off-by: default avatarYosry Ahmed <yosryahmed@google.com>
Signed-off-by: default avatarHao Luo <haoluo@google.com>
Link: https://lore.kernel.org/r/20220805214821.1058337-2-haoluo@google.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ca34ce29
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -146,6 +146,12 @@ that operate (change some property, perform some operation) on an object that
was obtained using an acquire kfunc. Such kfuncs need an unchanged pointer to
ensure the integrity of the operation being performed on the expected object.

2.4.6 KF_SLEEPABLE flag
-----------------------

The KF_SLEEPABLE flag is used for kfuncs that may sleep. Such kfuncs can only
be called by sleepable BPF programs (BPF_F_SLEEPABLE).

2.5 Registering the kfuncs
--------------------------

+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
 * for this case.
 */
#define KF_TRUSTED_ARGS (1 << 4) /* kfunc only takes trusted pointer arguments */
#define KF_SLEEPABLE   (1 << 5) /* kfunc may sleep */

struct btf;
struct btf_member;
+9 −0
Original line number Diff line number Diff line
@@ -6175,6 +6175,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
{
	enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
	bool rel = false, kptr_get = false, trusted_arg = false;
	bool sleepable = false;
	struct bpf_verifier_log *log = &env->log;
	u32 i, nargs, ref_id, ref_obj_id = 0;
	bool is_kfunc = btf_is_kernel(btf);
@@ -6212,6 +6213,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
		rel = kfunc_flags & KF_RELEASE;
		kptr_get = kfunc_flags & KF_KPTR_GET;
		trusted_arg = kfunc_flags & KF_TRUSTED_ARGS;
		sleepable = kfunc_flags & KF_SLEEPABLE;
	}

	/* check that BTF function arguments match actual types that the
@@ -6419,6 +6421,13 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
			func_name);
		return -EINVAL;
	}

	if (sleepable && !env->prog->aux->sleepable) {
		bpf_log(log, "kernel function %s is sleepable but the program is not\n",
			func_name);
		return -EINVAL;
	}

	/* returns argument register number > 0 in case of reference release kfunc */
	return rel ? ref_regno : 0;
}