Commit da11b417 authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by Daniel Borkmann

libbpf: teach libbpf about log_level bit 2

Allow bpf_prog_load_xattr() to specify log_level for program loading.

Teach libbpf to accept log_level with bit 2 set.

Increase default BPF_LOG_BUF_SIZE from 256k to 16M.
There is no downside to increase it to a maximum allowed by old kernels.
Existing 256k limit caused ENOSPC errors and users were not able to see
verifier error which is printed at the end of the verifier log.

If ENOSPC is hit, double the verifier log and try again to capture
the verifier error.
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 7a9f5c65
...@@ -223,7 +223,7 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, ...@@ -223,7 +223,7 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
return -EINVAL; return -EINVAL;
log_level = load_attr->log_level; log_level = load_attr->log_level;
if (log_level > 2 || (log_level && !log_buf)) if (log_level > (4 | 2 | 1) || (log_level && !log_buf))
return -EINVAL; return -EINVAL;
name_len = load_attr->name ? strlen(load_attr->name) : 0; name_len = load_attr->name ? strlen(load_attr->name) : 0;
......
...@@ -92,7 +92,7 @@ struct bpf_load_program_attr { ...@@ -92,7 +92,7 @@ struct bpf_load_program_attr {
#define MAPS_RELAX_COMPAT 0x01 #define MAPS_RELAX_COMPAT 0x01
/* Recommend log buffer size */ /* Recommend log buffer size */
#define BPF_LOG_BUF_SIZE (256 * 1024) #define BPF_LOG_BUF_SIZE (16 * 1024 * 1024) /* verifier maximum in kernels <= 5.1 */
LIBBPF_API int LIBBPF_API int
bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
char *log_buf, size_t log_buf_sz); char *log_buf, size_t log_buf_sz);
......
...@@ -152,6 +152,7 @@ struct bpf_program { ...@@ -152,6 +152,7 @@ struct bpf_program {
}; };
} *reloc_desc; } *reloc_desc;
int nr_reloc; int nr_reloc;
int log_level;
struct { struct {
int nr; int nr;
...@@ -1494,6 +1495,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, ...@@ -1494,6 +1495,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
{ {
struct bpf_load_program_attr load_attr; struct bpf_load_program_attr load_attr;
char *cp, errmsg[STRERR_BUFSIZE]; char *cp, errmsg[STRERR_BUFSIZE];
int log_buf_size = BPF_LOG_BUF_SIZE;
char *log_buf; char *log_buf;
int ret; int ret;
...@@ -1514,21 +1516,30 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, ...@@ -1514,21 +1516,30 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
load_attr.line_info = prog->line_info; load_attr.line_info = prog->line_info;
load_attr.line_info_rec_size = prog->line_info_rec_size; load_attr.line_info_rec_size = prog->line_info_rec_size;
load_attr.line_info_cnt = prog->line_info_cnt; load_attr.line_info_cnt = prog->line_info_cnt;
load_attr.log_level = prog->log_level;
if (!load_attr.insns || !load_attr.insns_cnt) if (!load_attr.insns || !load_attr.insns_cnt)
return -EINVAL; return -EINVAL;
log_buf = malloc(BPF_LOG_BUF_SIZE); retry_load:
log_buf = malloc(log_buf_size);
if (!log_buf) if (!log_buf)
pr_warning("Alloc log buffer for bpf loader error, continue without log\n"); pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
ret = bpf_load_program_xattr(&load_attr, log_buf, BPF_LOG_BUF_SIZE); ret = bpf_load_program_xattr(&load_attr, log_buf, log_buf_size);
if (ret >= 0) { if (ret >= 0) {
if (load_attr.log_level)
pr_debug("verifier log:\n%s", log_buf);
*pfd = ret; *pfd = ret;
ret = 0; ret = 0;
goto out; goto out;
} }
if (errno == ENOSPC) {
log_buf_size <<= 1;
free(log_buf);
goto retry_load;
}
ret = -LIBBPF_ERRNO__LOAD; ret = -LIBBPF_ERRNO__LOAD;
cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
pr_warning("load bpf program failed: %s\n", cp); pr_warning("load bpf program failed: %s\n", cp);
...@@ -2938,6 +2949,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, ...@@ -2938,6 +2949,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
bpf_program__set_expected_attach_type(prog, bpf_program__set_expected_attach_type(prog,
expected_attach_type); expected_attach_type);
prog->log_level = attr->log_level;
if (!first_prog) if (!first_prog)
first_prog = prog; first_prog = prog;
} }
......
...@@ -314,6 +314,7 @@ struct bpf_prog_load_attr { ...@@ -314,6 +314,7 @@ struct bpf_prog_load_attr {
enum bpf_prog_type prog_type; enum bpf_prog_type prog_type;
enum bpf_attach_type expected_attach_type; enum bpf_attach_type expected_attach_type;
int ifindex; int ifindex;
int log_level;
}; };
LIBBPF_API int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, LIBBPF_API int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment