diff mbox

[v10,01/12] bpf: add bpf_prog_add api for bulk prog refcnt

Message ID 1468955817-10604-2-git-send-email-bblanco@plumgrid.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Brenden Blanco July 19, 2016, 7:16 p.m. UTC
A subsystem may need to store many copies of a bpf program, each
deserving its own reference. Rather than requiring the caller to loop
one by one (with possible mid-loop failure), add a bulk bpf_prog_add
api.

Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
---
 include/linux/bpf.h  |  1 +
 kernel/bpf/syscall.c | 12 +++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

Comments

Alexei Starovoitov July 19, 2016, 9:46 p.m. UTC | #1
On Tue, Jul 19, 2016 at 12:16:46PM -0700, Brenden Blanco wrote:
> A subsystem may need to store many copies of a bpf program, each
> deserving its own reference. Rather than requiring the caller to loop
> one by one (with possible mid-loop failure), add a bulk bpf_prog_add
> api.
> 
> Signed-off-by: Brenden Blanco <bblanco@plumgrid.com>
> ---
>  include/linux/bpf.h  |  1 +
>  kernel/bpf/syscall.c | 12 +++++++++---
>  2 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index c13e92b..75a5ae6 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -224,6 +224,7 @@ void bpf_register_map_type(struct bpf_map_type_list *tl);
>  
>  struct bpf_prog *bpf_prog_get(u32 ufd);
>  struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type);
> +struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i);
>  struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog);
>  void bpf_prog_put(struct bpf_prog *prog);
>  
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index 96d938a..228f962 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -670,14 +670,20 @@ static struct bpf_prog *____bpf_prog_get(struct fd f)
>  	return f.file->private_data;
>  }
>  
> -struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
> +struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
>  {
> -	if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) {
> -		atomic_dec(&prog->aux->refcnt);
> +	if (atomic_add_return(i, &prog->aux->refcnt) > BPF_MAX_REFCNT) {
> +		atomic_sub(i, &prog->aux->refcnt);
>  		return ERR_PTR(-EBUSY);
>  	}
>  	return prog;
>  }
> +EXPORT_SYMBOL_GPL(bpf_prog_add);
> +
> +struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
> +{
> +	return bpf_prog_add(prog, 1);
> +}

that extension turned out to be smaller than I thought :)
Acked-by: Alexei Starovoitov <ast@kernel.org>
diff mbox

Patch

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index c13e92b..75a5ae6 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -224,6 +224,7 @@  void bpf_register_map_type(struct bpf_map_type_list *tl);
 
 struct bpf_prog *bpf_prog_get(u32 ufd);
 struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type);
+struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i);
 struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog);
 void bpf_prog_put(struct bpf_prog *prog);
 
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 96d938a..228f962 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -670,14 +670,20 @@  static struct bpf_prog *____bpf_prog_get(struct fd f)
 	return f.file->private_data;
 }
 
-struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
+struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
 {
-	if (atomic_inc_return(&prog->aux->refcnt) > BPF_MAX_REFCNT) {
-		atomic_dec(&prog->aux->refcnt);
+	if (atomic_add_return(i, &prog->aux->refcnt) > BPF_MAX_REFCNT) {
+		atomic_sub(i, &prog->aux->refcnt);
 		return ERR_PTR(-EBUSY);
 	}
 	return prog;
 }
+EXPORT_SYMBOL_GPL(bpf_prog_add);
+
+struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog)
+{
+	return bpf_prog_add(prog, 1);
+}
 
 static struct bpf_prog *__bpf_prog_get(u32 ufd, enum bpf_prog_type *type)
 {