summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2019-04-02 00:27:47 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2019-04-03 19:27:38 -0400
commitda11b417583ece875f862d84578259a2ab27ad86 (patch)
tree788118532f64d3e719781ebf2f4ba3fcc679fe14
parent7a9f5c65abcc9644b11738ca0815510cb5510eaf (diff)
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: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--tools/lib/bpf/bpf.c2
-rw-r--r--tools/lib/bpf/bpf.h2
-rw-r--r--tools/lib/bpf/libbpf.c16
-rw-r--r--tools/lib/bpf/libbpf.h1
4 files changed, 17 insertions, 4 deletions
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 9cd015574e83..a1db869a6fda 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -223,7 +223,7 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
223 return -EINVAL; 223 return -EINVAL;
224 224
225 log_level = load_attr->log_level; 225 log_level = load_attr->log_level;
226 if (log_level > 2 || (log_level && !log_buf)) 226 if (log_level > (4 | 2 | 1) || (log_level && !log_buf))
227 return -EINVAL; 227 return -EINVAL;
228 228
229 name_len = load_attr->name ? strlen(load_attr->name) : 0; 229 name_len = load_attr->name ? strlen(load_attr->name) : 0;
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 6ffdd79bea89..e2c0df7b831f 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -92,7 +92,7 @@ struct bpf_load_program_attr {
92#define MAPS_RELAX_COMPAT 0x01 92#define MAPS_RELAX_COMPAT 0x01
93 93
94/* Recommend log buffer size */ 94/* Recommend log buffer size */
95#define BPF_LOG_BUF_SIZE (256 * 1024) 95#define BPF_LOG_BUF_SIZE (16 * 1024 * 1024) /* verifier maximum in kernels <= 5.1 */
96LIBBPF_API int 96LIBBPF_API int
97bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, 97bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
98 char *log_buf, size_t log_buf_sz); 98 char *log_buf, size_t log_buf_sz);
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 11c25d9ea431..e1e4d35cf08e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -152,6 +152,7 @@ struct bpf_program {
152 }; 152 };
153 } *reloc_desc; 153 } *reloc_desc;
154 int nr_reloc; 154 int nr_reloc;
155 int log_level;
155 156
156 struct { 157 struct {
157 int nr; 158 int nr;
@@ -1494,6 +1495,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
1494{ 1495{
1495 struct bpf_load_program_attr load_attr; 1496 struct bpf_load_program_attr load_attr;
1496 char *cp, errmsg[STRERR_BUFSIZE]; 1497 char *cp, errmsg[STRERR_BUFSIZE];
1498 int log_buf_size = BPF_LOG_BUF_SIZE;
1497 char *log_buf; 1499 char *log_buf;
1498 int ret; 1500 int ret;
1499 1501
@@ -1514,21 +1516,30 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
1514 load_attr.line_info = prog->line_info; 1516 load_attr.line_info = prog->line_info;
1515 load_attr.line_info_rec_size = prog->line_info_rec_size; 1517 load_attr.line_info_rec_size = prog->line_info_rec_size;
1516 load_attr.line_info_cnt = prog->line_info_cnt; 1518 load_attr.line_info_cnt = prog->line_info_cnt;
1519 load_attr.log_level = prog->log_level;
1517 if (!load_attr.insns || !load_attr.insns_cnt) 1520 if (!load_attr.insns || !load_attr.insns_cnt)
1518 return -EINVAL; 1521 return -EINVAL;
1519 1522
1520 log_buf = malloc(BPF_LOG_BUF_SIZE); 1523retry_load:
1524 log_buf = malloc(log_buf_size);
1521 if (!log_buf) 1525 if (!log_buf)
1522 pr_warning("Alloc log buffer for bpf loader error, continue without log\n"); 1526 pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
1523 1527
1524 ret = bpf_load_program_xattr(&load_attr, log_buf, BPF_LOG_BUF_SIZE); 1528 ret = bpf_load_program_xattr(&load_attr, log_buf, log_buf_size);
1525 1529
1526 if (ret >= 0) { 1530 if (ret >= 0) {
1531 if (load_attr.log_level)
1532 pr_debug("verifier log:\n%s", log_buf);
1527 *pfd = ret; 1533 *pfd = ret;
1528 ret = 0; 1534 ret = 0;
1529 goto out; 1535 goto out;
1530 } 1536 }
1531 1537
1538 if (errno == ENOSPC) {
1539 log_buf_size <<= 1;
1540 free(log_buf);
1541 goto retry_load;
1542 }
1532 ret = -LIBBPF_ERRNO__LOAD; 1543 ret = -LIBBPF_ERRNO__LOAD;
1533 cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg)); 1544 cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
1534 pr_warning("load bpf program failed: %s\n", cp); 1545 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 bpf_program__set_expected_attach_type(prog, 2949 bpf_program__set_expected_attach_type(prog,
2939 expected_attach_type); 2950 expected_attach_type);
2940 2951
2952 prog->log_level = attr->log_level;
2941 if (!first_prog) 2953 if (!first_prog)
2942 first_prog = prog; 2954 first_prog = prog;
2943 } 2955 }
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index c70785cc8ef5..531323391d07 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -314,6 +314,7 @@ struct bpf_prog_load_attr {
314 enum bpf_prog_type prog_type; 314 enum bpf_prog_type prog_type;
315 enum bpf_attach_type expected_attach_type; 315 enum bpf_attach_type expected_attach_type;
316 int ifindex; 316 int ifindex;
317 int log_level;
317}; 318};
318 319
319LIBBPF_API int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, 320LIBBPF_API int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,