[1/1] bpf: libbpf: retry loading program on EAGAIN

Message ID 20190108135800.31429-2-lmb@cloudflare.com
State Accepted
Delegated to: BPF Maintainers
Headers show
Series
  • bpf: libbpf: retry loading program on EAGAIN
Related show

Commit Message

Lorenz Bauer Jan. 8, 2019, 1:58 p.m.
Commit c3494801cd1785e2 ("bpf: check pending signals while
verifying programs") makes it possible for the BPF_PROG_LOAD
to fail with EAGAIN. Retry unconditionally in this case.

Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>
---
 tools/lib/bpf/bpf.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

Comments

Daniel Borkmann Jan. 15, 2019, 8:53 p.m. | #1
On 01/08/2019 02:58 PM, Lorenz Bauer wrote:
> Commit c3494801cd1785e2 ("bpf: check pending signals while
> verifying programs") makes it possible for the BPF_PROG_LOAD
> to fail with EAGAIN. Retry unconditionally in this case.
> 
> Signed-off-by: Lorenz Bauer <lmb@cloudflare.com>

Bit back and forth whether libbpf should actually do this and not
the application itself, otoh, until this point there was nothing
returning EAGAIN either during load so it avoids potential breakage,
anyway, applied, thanks!

Patch

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 3caaa3428774..88cbd110ae58 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -65,6 +65,17 @@  static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
 	return syscall(__NR_bpf, cmd, attr, size);
 }
 
+static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
+{
+	int fd;
+
+	do {
+		fd = sys_bpf(BPF_PROG_LOAD, attr, size);
+	} while (fd < 0 && errno == EAGAIN);
+
+	return fd;
+}
+
 int bpf_create_map_xattr(const struct bpf_create_map_attr *create_attr)
 {
 	__u32 name_len = create_attr->name ? strlen(create_attr->name) : 0;
@@ -232,7 +243,7 @@  int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
 	memcpy(attr.prog_name, load_attr->name,
 	       min(name_len, BPF_OBJ_NAME_LEN - 1));
 
-	fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+	fd = sys_bpf_prog_load(&attr, sizeof(attr));
 	if (fd >= 0)
 		return fd;
 
@@ -269,7 +280,7 @@  int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
 			break;
 		}
 
-		fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+		fd = sys_bpf_prog_load(&attr, sizeof(attr));
 
 		if (fd >= 0)
 			goto done;
@@ -283,7 +294,7 @@  int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
 	attr.log_size = log_buf_sz;
 	attr.log_level = 1;
 	log_buf[0] = 0;
-	fd = sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+	fd = sys_bpf_prog_load(&attr, sizeof(attr));
 done:
 	free(finfo);
 	free(linfo);
@@ -328,7 +339,7 @@  int bpf_verify_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 	attr.kern_version = kern_version;
 	attr.prog_flags = prog_flags;
 
-	return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+	return sys_bpf_prog_load(&attr, sizeof(attr));
 }
 
 int bpf_map_update_elem(int fd, const void *key, const void *value,