Skip to contentSkip to conversation

Minor BPF updates

PATCH In review Daniel Borkmann 3 participants 10 messages Jul 30, 2015

Subsystems (11)
lore
Share & tools
lore

Daniel Borkmann

author maintainer
#0 lore raw

cover Minor BPF updates

Various minor misc updates.

Thanks!

Daniel Borkmann (4):
test_bpf: assign type to native eBPF test cases
bpf: provide helper that indicates eBPF was migrated bpf, x86/sparc: show actual number of passes in bpf_jit_dump
bpf: also show process name/pid in bpf_jit_dump

 arch/s390/net/bpf_jit_comp.c  |  2 +-
 arch/sparc/net/bpf_jit_comp.c |  2 +-
 arch/x86/net/bpf_jit_comp.c   |  2 +-
 include/linux/filter.h        | 16 ++++++++++++++--
 lib/test_bpf.c                |  2 ++
 5 files changed, 19 insertions(+), 5 deletions(-)
Signature · 1 line
1.9.3
author maintainer
#1 lore raw

PATCH 1/4 test_bpf: assign type to native eBPF test cases

As JITs start to perform optimizations whether to clear A and X on eBPF programs in the prologue, we should actually assign a program type to the native eBPF test cases. It doesn't really matter which program type, as these instructions don't go through the verifier, but it needs to be a type != BPF_PROG_TYPE_UNSPEC. This reflects eBPF programs loaded via bpf(2) system call (!= type unspec) vs. classic BPF to eBPF migrations (== type unspec).

---
 lib/test_bpf.c | 2 ++
 1 file changed, 2 insertions(+)
lib/test_bpf.c +2 -0
index 8b5e66f..3afddf2 100644
@@ -4613,6 +4613,8 @@ static struct bpf_prog *generate_filter(int which, int *err)
 		}
 
 		fp->len = flen;
+		/* Type doesn't really matter here as long as it's not unspec. */
+		fp->type = BPF_PROG_TYPE_SOCKET_FILTER;
 		memcpy(fp->insnsi, fptr, fp->len * sizeof(struct bpf_insn));
 
 		bpf_prog_select_runtime(fp);
Signature · 1 line
1.9.3
Acked-by on v1 1/4
#2 lore raw

Re: [PATCH net-next 1/4] test_bpf: assign type to native eBPF test cases

Quoted 10 lines · Daniel Borkmann

As JITs start to perform optimizations whether to clear A and X on eBPF programs in the prologue, we should actually assign a program type to the native eBPF test cases. It doesn't really matter which program type, as these instructions don't go through the verifier, but it needs to be a type != BPF_PROG_TYPE_UNSPEC. This reflects eBPF programs loaded via bpf(2) system call (!= type unspec) vs. classic BPF to eBPF migrations (== type unspec).

author maintainer
#3 lore raw

PATCH 2/4 bpf: provide helper that indicates eBPF was migrated

In reply to Daniel Borkmann

During recent discussions we had with Michael, we found that it would be useful to have an indicator that tells the JIT that an eBPF program had been migrated from classic instructions into eBPF instructions, as only in that case A and X need to be cleared in the prologue. Such eBPF programs do not set a particular type, but all have BPF_PROG_TYPE_UNSPEC. Thus, introduce a small helper for cde66c2d88da ("s390/bpf: Only clear A and X for converted BPF programs") and possibly others in future.

---
 arch/s390/net/bpf_jit_comp.c |  2 +-
 include/linux/filter.h       | 10 ++++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
arch/s390/net/bpf_jit_comp.c +1 -1
index bbbac6d..9f4bbc0 100644
@@ -1245,7 +1245,7 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp)
 	jit->lit = jit->lit_start;
 	jit->prg = 0;
 
-	bpf_jit_prologue(jit, fp->type == BPF_PROG_TYPE_UNSPEC);
+	bpf_jit_prologue(jit, bpf_prog_was_classic(fp));
 	for (i = 0; i < fp->len; i += insn_count) {
 		insn_count = bpf_jit_insn(jit, fp, i);
 		if (insn_count < 0)
include/linux/filter.h +10 -0
index 69d0055..6b02549 100644
@@ -354,6 +354,16 @@ static inline unsigned int bpf_prog_size(unsigned int proglen)
 		   offsetof(struct bpf_prog, insns[proglen]));
 }
 
+static inline bool bpf_prog_was_classic(const struct bpf_prog *prog)
+{
+	/* When classic BPF programs have been loaded and the arch
+	 * does not have a classic BPF JIT (anymore), they have been
+	 * converted via bpf_migrate_filter() to eBPF and thus always
+	 * have an unspec program type.
+	 */
+	return prog->type == BPF_PROG_TYPE_UNSPEC;
+}
+
 #define bpf_classic_proglen(fprog) (fprog->len * sizeof(fprog->filter[0]))
 
 #ifdef CONFIG_DEBUG_SET_MODULE_RONX
Signature · 1 line
1.9.3
Acked-by on v1 2/4
#4 lore raw

Re: [PATCH net-next 2/4] bpf: provide helper that indicates eBPF was migrated

Quoted 10 lines · Daniel Borkmann

During recent discussions we had with Michael, we found that it would be useful to have an indicator that tells the JIT that an eBPF program had been migrated from classic instructions into eBPF instructions, as only in that case A and X need to be cleared in the prologue. Such eBPF programs do not set a particular type, but all have BPF_PROG_TYPE_UNSPEC. Thus, introduce a small helper for cde66c2d88da ("s390/bpf: Only clear A and X for converted BPF programs") and possibly others in future.

author maintainer
#5 lore raw

PATCH 3/4 bpf, x86/sparc: show actual number of passes in bpf_jit_dump

In reply to Daniel Borkmann

When bpf_jit_compile() got split into two functions via commit f3c2af7ba17a ("net: filter: x86: split bpf_jit_compile()"), bpf_jit_dump() was changed to always show 0 as number of compiler passes. Change it to dump the actual number. Also on sparc, we count passes starting from 0, so add 1 for the debug dump as well.

---
 arch/sparc/net/bpf_jit_comp.c | 2 +-
 arch/x86/net/bpf_jit_comp.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/sparc/net/bpf_jit_comp.c +1 -1
index 7931eee..f8b9f71 100644
@@ -807,7 +807,7 @@ cond_branch:			f_offset = addrs[i + filter[i].jf];
 	}
 
 	if (bpf_jit_enable > 1)
-		bpf_jit_dump(flen, proglen, pass, image);
+		bpf_jit_dump(flen, proglen, pass + 1, image);
 
 	if (image) {
 		bpf_flush_icache(image, image + proglen);
arch/x86/net/bpf_jit_comp.c +1 -1
index 6c335a8..c08000b 100644
@@ -1103,7 +1103,7 @@ void bpf_int_jit_compile(struct bpf_prog *prog)
 	}
 
 	if (bpf_jit_enable > 1)
-		bpf_jit_dump(prog->len, proglen, 0, image);
+		bpf_jit_dump(prog->len, proglen, pass + 1, image);
 
 	if (image) {
 		bpf_flush_icache(header, image + proglen);
Signature · 1 line
1.9.3
Acked-by on v1 3/4
#6 lore raw

Re: [PATCH net-next 3/4] bpf, x86/sparc: show actual number of passes in bpf_jit_dump

Quoted 7 lines · Daniel Borkmann

When bpf_jit_compile() got split into two functions via commit f3c2af7ba17a ("net: filter: x86: split bpf_jit_compile()"), bpf_jit_dump() was changed to always show 0 as number of compiler passes. Change it to dump the actual number. Also on sparc, we count passes starting from 0, so add 1 for the debug dump as well.

author maintainer
#7 lore raw

PATCH 4/4 bpf: also show process name/pid in bpf_jit_dump

In reply to Daniel Borkmann

It can be useful for testing to see the actual process/pid who is loading a given filter. I was running some BPF test program and noticed unusual filter loads from time to time, triggered by some other application in the background. bpf_jit_disasm is still working after this change.

---
 include/linux/filter.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/filter.h +4 -2
index 6b02549..fa2cab9 100644
@@ -12,6 +12,7 @@
 #include <linux/linkage.h>
 #include <linux/printk.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
 
 #include <asm/cacheflush.h>
 
@@ -438,8 +439,9 @@ void bpf_jit_free(struct bpf_prog *fp);
 static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen,
 				u32 pass, void *image)
 {
-	pr_err("flen=%u proglen=%u pass=%u image=%pK\n",
-	       flen, proglen, pass, image);
+	pr_err("flen=%u proglen=%u pass=%u image=%pK from=%s pid=%d\n", flen,
+	       proglen, pass, image, current->comm, task_pid_nr(current));
+
 	if (image)
 		print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET,
 			       16, 1, image, proglen, false);
Signature · 1 line
1.9.3
Acked-by on v1 4/4
#8 lore raw

Re: [PATCH net-next 4/4] bpf: also show process name/pid in bpf_jit_dump

Quoted 6 lines · Daniel Borkmann

It can be useful for testing to see the actual process/pid who is loading a given filter. I was running some BPF test program and noticed unusual filter loads from time to time, triggered by some other application in the background. bpf_jit_disasm is still working after this change.