diff mbox series

[12/23] bpf: add IOURING program type

Message ID 3883680d4638504e3dcf79bf1c15d548a9cb7f3e.1621424513.git.asml.silence@gmail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series io_uring BPF requests | expand

Checks

Context Check Description
netdev/tree_selection success Not a local patch

Commit Message

Pavel Begunkov May 19, 2021, 2:13 p.m. UTC
Draft a new program type BPF_PROG_TYPE_IOURING, which will be used by
io_uring to execute BPF-based requests.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
 fs/io_uring.c             | 21 +++++++++++++++++++++
 include/linux/bpf_types.h |  2 ++
 include/uapi/linux/bpf.h  |  1 +
 kernel/bpf/syscall.c      |  1 +
 kernel/bpf/verifier.c     |  5 ++++-
 5 files changed, 29 insertions(+), 1 deletion(-)

Comments

Song Liu May 20, 2021, 11:34 p.m. UTC | #1
> On May 19, 2021, at 7:13 AM, Pavel Begunkov <asml.silence@gmail.com> wrote:
> 
> Draft a new program type BPF_PROG_TYPE_IOURING, which will be used by
> io_uring to execute BPF-based requests.
> 
> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
> ---
> fs/io_uring.c             | 21 +++++++++++++++++++++
> include/linux/bpf_types.h |  2 ++
> include/uapi/linux/bpf.h  |  1 +
> kernel/bpf/syscall.c      |  1 +
> kernel/bpf/verifier.c     |  5 ++++-
> 5 files changed, 29 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/io_uring.c b/fs/io_uring.c
> index 1a4c9e513ac9..882b16b5e5eb 100644
> --- a/fs/io_uring.c
> +++ b/fs/io_uring.c
> @@ -10201,6 +10201,27 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
> 	return ret;
> }
> 
> +static const struct bpf_func_proto *
> +io_bpf_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> +{
> +	return bpf_base_func_proto(func_id);
> +}
> +
> +static bool io_bpf_is_valid_access(int off, int size,
> +				   enum bpf_access_type type,
> +				   const struct bpf_prog *prog,
> +				   struct bpf_insn_access_aux *info)
> +{
> +	return false;
> +}
> +
> +const struct bpf_prog_ops bpf_io_uring_prog_ops = {};
> +
> +const struct bpf_verifier_ops bpf_io_uring_verifier_ops = {
> +	.get_func_proto		= io_bpf_func_proto,
> +	.is_valid_access	= io_bpf_is_valid_access,
> +};
> +
> SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
> 		void __user *, arg, unsigned int, nr_args)
> {
> diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
> index 99f7fd657d87..d0b7954887bd 100644
> --- a/include/linux/bpf_types.h
> +++ b/include/linux/bpf_types.h
> @@ -77,6 +77,8 @@ BPF_PROG_TYPE(BPF_PROG_TYPE_LSM, lsm,
> 	       void *, void *)
> #endif /* CONFIG_BPF_LSM */
> #endif
> +BPF_PROG_TYPE(BPF_PROG_TYPE_IOURING, bpf_io_uring,
> +	      void *, void *)
> 
> BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
> BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
> index 4ba4ef0ff63a..de544f0fbeef 100644
> --- a/include/uapi/linux/bpf.h
> +++ b/include/uapi/linux/bpf.h
> @@ -206,6 +206,7 @@ enum bpf_prog_type {
> 	BPF_PROG_TYPE_EXT,
> 	BPF_PROG_TYPE_LSM,
> 	BPF_PROG_TYPE_SK_LOOKUP,
> +	BPF_PROG_TYPE_IOURING,
> };
> 
> enum bpf_attach_type {
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 250503482cda..6ef7a26f4dc3 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -2041,6 +2041,7 @@ static bool is_net_admin_prog_type(enum bpf_prog_type prog_type)
> 	case BPF_PROG_TYPE_CGROUP_SOCKOPT:
> 	case BPF_PROG_TYPE_CGROUP_SYSCTL:
> 	case BPF_PROG_TYPE_SOCK_OPS:
> +	case BPF_PROG_TYPE_IOURING:
> 	case BPF_PROG_TYPE_EXT: /* extends any prog */
> 		return true;
> 	case BPF_PROG_TYPE_CGROUP_SKB:
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 0399ac092b36..2a53f44618a7 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -8558,6 +8558,9 @@ static int check_return_code(struct bpf_verifier_env *env)
> 	case BPF_PROG_TYPE_SK_LOOKUP:
> 		range = tnum_range(SK_DROP, SK_PASS);
> 		break;
> +	case BPF_PROG_TYPE_IOURING:
> +		range = tnum_const(0);
> +		break;
> 	case BPF_PROG_TYPE_EXT:
> 		/* freplace program can return anything as its return value
> 		 * depends on the to-be-replaced kernel func or bpf program.
> @@ -12560,7 +12563,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
> 	u64 key;
> 
> 	if (prog->aux->sleepable && prog->type != BPF_PROG_TYPE_TRACING &&
> -	    prog->type != BPF_PROG_TYPE_LSM) {
> +	    prog->type != BPF_PROG_TYPE_LSM && prog->type != BPF_PROG_TYPE_IOURING) {

Is IOURING program sleepable? If so, please highlight that in the commit log 
and update the warning below. 

> 		verbose(env, "Only fentry/fexit/fmod_ret and lsm programs can be sleepable\n");
> 		return -EINVAL;
> 	}
> -- 
> 2.31.1
>
Pavel Begunkov May 21, 2021, 12:56 a.m. UTC | #2
On 5/21/21 12:34 AM, Song Liu wrote:
>> On May 19, 2021, at 7:13 AM, Pavel Begunkov <asml.silence@gmail.com> wrote:
>>
>> Draft a new program type BPF_PROG_TYPE_IOURING, which will be used by
>> io_uring to execute BPF-based requests.
>>
>> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
>> ---
>> fs/io_uring.c             | 21 +++++++++++++++++++++
>> include/linux/bpf_types.h |  2 ++
>> include/uapi/linux/bpf.h  |  1 +
>> kernel/bpf/syscall.c      |  1 +
>> kernel/bpf/verifier.c     |  5 ++++-
>> 5 files changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/io_uring.c b/fs/io_uring.c
>> index 1a4c9e513ac9..882b16b5e5eb 100644
[...]
>> +BPF_PROG_TYPE(BPF_PROG_TYPE_IOURING, bpf_io_uring,
>> +	      void *, void *)
>>
>> BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
>> BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 4ba4ef0ff63a..de544f0fbeef 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -206,6 +206,7 @@ enum bpf_prog_type {
>> 	BPF_PROG_TYPE_EXT,
>> 	BPF_PROG_TYPE_LSM,
>> 	BPF_PROG_TYPE_SK_LOOKUP,
>> +	BPF_PROG_TYPE_IOURING,
>> };
>>
>> enum bpf_attach_type {
>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>> index 250503482cda..6ef7a26f4dc3 100644
>> --- a/kernel/bpf/syscall.c
>> +++ b/kernel/bpf/syscall.c
>> @@ -2041,6 +2041,7 @@ static bool is_net_admin_prog_type(enum bpf_prog_type prog_type)
>> 	case BPF_PROG_TYPE_CGROUP_SOCKOPT:
>> 	case BPF_PROG_TYPE_CGROUP_SYSCTL:
>> 	case BPF_PROG_TYPE_SOCK_OPS:
>> +	case BPF_PROG_TYPE_IOURING:
>> 	case BPF_PROG_TYPE_EXT: /* extends any prog */
>> 		return true;
>> 	case BPF_PROG_TYPE_CGROUP_SKB:
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 0399ac092b36..2a53f44618a7 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -8558,6 +8558,9 @@ static int check_return_code(struct bpf_verifier_env *env)
>> 	case BPF_PROG_TYPE_SK_LOOKUP:
>> 		range = tnum_range(SK_DROP, SK_PASS);
>> 		break;
>> +	case BPF_PROG_TYPE_IOURING:
>> +		range = tnum_const(0);
>> +		break;
>> 	case BPF_PROG_TYPE_EXT:
>> 		/* freplace program can return anything as its return value
>> 		 * depends on the to-be-replaced kernel func or bpf program.
>> @@ -12560,7 +12563,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
>> 	u64 key;
>>
>> 	if (prog->aux->sleepable && prog->type != BPF_PROG_TYPE_TRACING &&
>> -	    prog->type != BPF_PROG_TYPE_LSM) {
>> +	    prog->type != BPF_PROG_TYPE_LSM && prog->type != BPF_PROG_TYPE_IOURING) {
> 
> Is IOURING program sleepable? If so, please highlight that in the commit log 

Supposed to work with both, sleepable and not, but with different set
of helpers. e.g. can't submit requests nor do bpf_copy_from_user() if
can't sleep. The only other difference in handling is rcu around
non-sleepable, but please shut out if I forgot anything

> and update the warning below. 

Sure

> 
>> 		verbose(env, "Only fentry/fexit/fmod_ret and lsm programs can be sleepable\n");
>> 		return -EINVAL;
>> 	}
>> -- 
>> 2.31.1
>>
>
diff mbox series

Patch

diff --git a/fs/io_uring.c b/fs/io_uring.c
index 1a4c9e513ac9..882b16b5e5eb 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -10201,6 +10201,27 @@  static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode,
 	return ret;
 }
 
+static const struct bpf_func_proto *
+io_bpf_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
+{
+	return bpf_base_func_proto(func_id);
+}
+
+static bool io_bpf_is_valid_access(int off, int size,
+				   enum bpf_access_type type,
+				   const struct bpf_prog *prog,
+				   struct bpf_insn_access_aux *info)
+{
+	return false;
+}
+
+const struct bpf_prog_ops bpf_io_uring_prog_ops = {};
+
+const struct bpf_verifier_ops bpf_io_uring_verifier_ops = {
+	.get_func_proto		= io_bpf_func_proto,
+	.is_valid_access	= io_bpf_is_valid_access,
+};
+
 SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
 		void __user *, arg, unsigned int, nr_args)
 {
diff --git a/include/linux/bpf_types.h b/include/linux/bpf_types.h
index 99f7fd657d87..d0b7954887bd 100644
--- a/include/linux/bpf_types.h
+++ b/include/linux/bpf_types.h
@@ -77,6 +77,8 @@  BPF_PROG_TYPE(BPF_PROG_TYPE_LSM, lsm,
 	       void *, void *)
 #endif /* CONFIG_BPF_LSM */
 #endif
+BPF_PROG_TYPE(BPF_PROG_TYPE_IOURING, bpf_io_uring,
+	      void *, void *)
 
 BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY, array_map_ops)
 BPF_MAP_TYPE(BPF_MAP_TYPE_PERCPU_ARRAY, percpu_array_map_ops)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 4ba4ef0ff63a..de544f0fbeef 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -206,6 +206,7 @@  enum bpf_prog_type {
 	BPF_PROG_TYPE_EXT,
 	BPF_PROG_TYPE_LSM,
 	BPF_PROG_TYPE_SK_LOOKUP,
+	BPF_PROG_TYPE_IOURING,
 };
 
 enum bpf_attach_type {
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 250503482cda..6ef7a26f4dc3 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2041,6 +2041,7 @@  static bool is_net_admin_prog_type(enum bpf_prog_type prog_type)
 	case BPF_PROG_TYPE_CGROUP_SOCKOPT:
 	case BPF_PROG_TYPE_CGROUP_SYSCTL:
 	case BPF_PROG_TYPE_SOCK_OPS:
+	case BPF_PROG_TYPE_IOURING:
 	case BPF_PROG_TYPE_EXT: /* extends any prog */
 		return true;
 	case BPF_PROG_TYPE_CGROUP_SKB:
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0399ac092b36..2a53f44618a7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8558,6 +8558,9 @@  static int check_return_code(struct bpf_verifier_env *env)
 	case BPF_PROG_TYPE_SK_LOOKUP:
 		range = tnum_range(SK_DROP, SK_PASS);
 		break;
+	case BPF_PROG_TYPE_IOURING:
+		range = tnum_const(0);
+		break;
 	case BPF_PROG_TYPE_EXT:
 		/* freplace program can return anything as its return value
 		 * depends on the to-be-replaced kernel func or bpf program.
@@ -12560,7 +12563,7 @@  static int check_attach_btf_id(struct bpf_verifier_env *env)
 	u64 key;
 
 	if (prog->aux->sleepable && prog->type != BPF_PROG_TYPE_TRACING &&
-	    prog->type != BPF_PROG_TYPE_LSM) {
+	    prog->type != BPF_PROG_TYPE_LSM && prog->type != BPF_PROG_TYPE_IOURING) {
 		verbose(env, "Only fentry/fexit/fmod_ret and lsm programs can be sleepable\n");
 		return -EINVAL;
 	}