All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
@ 2015-12-17  5:23 Wang Nan
  2015-12-17  5:23 ` [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error Wang Nan
                   ` (10 more replies)
  0 siblings, 11 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Since we already have libbpf in tools/lib, we don't need to maintain
another bpf loader and operations library in samples/bpf.

In patchset:

 Patch 1/10 - 7/10 improves libbpf, add missing features to support
 samples,

 Patch 8/10 adds utils.[ch], which creates similar API like old
 bpf_load.c and libbpf.c.

 Patch 9/10 replace all sampels to use API provides by utils.[ch] and
 libbpf.

 Patch 10/10 removes unneeded files.

 Cc: Alexei Starovoitov <ast@kernel.org>
 Cc: Alex Gartrell <agartrell@fb.com>
 Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
 Cc: Brenden Blanco <bblanco@plumgrid.com>
 Cc: Daniel Borkmann <daniel@iogearbox.net>
 Cc: Daniel Wagner <daniel.wagner@bmw-carit.de>
 Cc: David S. Miller <davem@davemloft.net>
 Cc: Ingo Molnar <mingo@kernel.org>
 Cc: Jiri Olsa <jolsa@kernel.org>
 Cc: Kaixu Xia <xiakaixu@huawei.com>
 Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
 Cc: Yang Shi <yang.shi@linaro.org>

Wang Nan (10):
  bpf samples: bpf: Fix tracex5_kern.c compiling error
  bpf tools: Define LD and RM in Makefile for 'make -R'
  bpf tools: Add const decoretor to 'license' and 'insns' for
    bpf_load_program()
  bpf tools: Switch to uapi style type names
  bpf tools: Support load different type of programs
  bpf tools: Support new map operations
  bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET
  bpf samples: Add utils.[ch] for using BPF
  bpf samples: Uses libbpf in tools/lib to deal with BPF operations
  bpf samples: Remove old BPF helpers

 samples/bpf/Makefile              |  65 +++----
 samples/bpf/bpf_load.c            | 345 --------------------------------------
 samples/bpf/bpf_load.h            |  27 ---
 samples/bpf/fds_example.c         |  26 +--
 samples/bpf/include/linux/err.h   |  56 +++++++
 samples/bpf/lathist_user.c        |  13 +-
 samples/bpf/libbpf.c              | 154 -----------------
 samples/bpf/sock_example.c        |  13 +-
 samples/bpf/sockex1_kern.c        |   2 +
 samples/bpf/sockex1_user.c        |  27 +--
 samples/bpf/sockex2_kern.c        |   2 +
 samples/bpf/sockex2_user.c        |  26 +--
 samples/bpf/sockex3_kern.c        |   2 +
 samples/bpf/sockex3_user.c        |  23 ++-
 samples/bpf/test_maps.c           |  80 ++++-----
 samples/bpf/test_verifier.c       |  13 +-
 samples/bpf/trace_output_user.c   |  17 +-
 samples/bpf/tracex1_user.c        |   9 +-
 samples/bpf/tracex2_user.c        |  31 ++--
 samples/bpf/tracex3_user.c        |  15 +-
 samples/bpf/tracex4_user.c        |  15 +-
 samples/bpf/tracex5_kern.c        |   1 +
 samples/bpf/tracex5_user.c        |   9 +-
 samples/bpf/tracex6_user.c        |  16 +-
 samples/bpf/utils.c               | 276 ++++++++++++++++++++++++++++++
 samples/bpf/{libbpf.h => utils.h} |  58 ++++---
 tools/lib/bpf/Makefile            |   2 +
 tools/lib/bpf/bpf.c               |  65 ++++++-
 tools/lib/bpf/bpf.h               |  16 +-
 tools/lib/bpf/libbpf.c            |  43 ++++-
 tools/lib/bpf/libbpf.h            |  16 ++
 31 files changed, 718 insertions(+), 745 deletions(-)
 delete mode 100644 samples/bpf/bpf_load.c
 delete mode 100644 samples/bpf/bpf_load.h
 create mode 100644 samples/bpf/include/linux/err.h
 delete mode 100644 samples/bpf/libbpf.c
 create mode 100644 samples/bpf/utils.c
 rename samples/bpf/{libbpf.h => utils.h} (81%)

-- 
1.8.3.4


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 02/10] bpf tools: Define LD and RM in Makefile for 'make -R' Wang Nan
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan, Alexei Starovoitov

LLVM report compiling error:

 /kpathsamples/bpf/tracex5_kern.c:33:15: error: use of undeclared identifier '__NR_getuid'; did you
       mean '__NR_vgetcpu'?
         if (sd.nr >= __NR_getuid && sd.nr <= __NR_getsid) {
                      ^~~~~~~~~~~
                      __NR_vgetcpu
 /kpath/arch/x86/include/uapi/asm/vsyscall.h:7:2: note: '__NR_vgetcpu' declared here
         __NR_vgetcpu,

This patch fix it by adding asm/unistd.h to it.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: David S. Miller <davem@davemloft.net>
---
 samples/bpf/tracex5_kern.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/samples/bpf/tracex5_kern.c b/samples/bpf/tracex5_kern.c
index b3f4295..2964efd 100644
--- a/samples/bpf/tracex5_kern.c
+++ b/samples/bpf/tracex5_kern.c
@@ -8,6 +8,7 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include <uapi/linux/seccomp.h>
+#include <asm/unistd.h>
 #include "bpf_helpers.h"
 
 #define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 02/10] bpf tools: Define LD and RM in Makefile for 'make -R'
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
  2015-12-17  5:23 ` [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 03/10] bpf tools: Add const decoretor to 'license' and 'insns' for bpf_load_program() Wang Nan
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Building libbpf with 'make -R' causes error:

 $ make -R

 Auto-detecting system features:
 ...                        libelf: [ on  ]
 ...                           bpf: [ on  ]

   CC       fixdep.o
   LD       fixdep-in.o
 /bin/sh: -r: command not found
 make[2]: *** [fixdep-in.o] Error 127
 make[1]: *** [fixdep-in.o] Error 2
 make: *** [fixdep] Error 2

Makefile for libbpf requires $(LD) and $(RM), but in case of 'make -R'
the builtin variables are gone. This patch define default RM and LD so
it won't fail in 'make -R'.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/lib/bpf/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 0b6e013..7bec12f 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -5,6 +5,8 @@ BPF_PATCHLEVEL = 0
 BPF_EXTRAVERSION = 1
 
 MAKEFLAGS += --no-print-directory
+RM ?= rm -f
+LD ?= $(CROSS_COMPILE)ld
 
 ifeq ($(srctree),)
 srctree := $(patsubst %/,%,$(dir $(shell pwd)))
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 03/10] bpf tools: Add const decoretor to 'license' and 'insns' for bpf_load_program()
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
  2015-12-17  5:23 ` [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error Wang Nan
  2015-12-17  5:23 ` [PATCH 02/10] bpf tools: Define LD and RM in Makefile for 'make -R' Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 04/10] bpf tools: Switch to uapi style type names Wang Nan
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Actually 'license' and 'insns' are const pointer. Before this patch
using 'bpf_load_program(... "GPL", ...)' triggers a warning, which is
unnecessary.

This patch makes these two arguments const pointers.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/bpf.c | 8 ++++----
 tools/lib/bpf/bpf.h | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 1f91cc9..88e6a46 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -55,8 +55,8 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size,
 	return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
 }
 
-int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
-		     size_t insns_cnt, char *license,
+int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
+		     size_t insns_cnt, const char *license,
 		     u32 kern_version, char *log_buf, size_t log_buf_sz)
 {
 	int fd;
@@ -65,8 +65,8 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
 	bzero(&attr, sizeof(attr));
 	attr.prog_type = type;
 	attr.insn_cnt = (__u32)insns_cnt;
-	attr.insns = ptr_to_u64(insns);
-	attr.license = ptr_to_u64(license);
+	attr.insns = ptr_to_u64((void *)insns);
+	attr.license = ptr_to_u64((void *)license);
 	attr.log_buf = ptr_to_u64(NULL);
 	attr.log_size = 0;
 	attr.log_level = 0;
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index a764655..00cfeae 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -15,8 +15,8 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
 
 /* Recommend log buffer size */
 #define BPF_LOG_BUF_SIZE 65536
-int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
-		     size_t insns_cnt, char *license,
+int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
+		     size_t insns_cnt, const char *license,
 		     u32 kern_version, char *log_buf,
 		     size_t log_buf_sz);
 
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 04/10] bpf tools: Switch to uapi style type names
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (2 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 03/10] bpf tools: Add const decoretor to 'license' and 'insns' for bpf_load_program() Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 05/10] bpf tools: Support load different type of programs Wang Nan
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Types "u64, u32" don't exist in uapi header (linux/types.h). Because of
that directly include bpf.h causes error.

This patch fixes this by replacing all occurrences of "u32, u64" in API
to "__u32, __u64". The later can be found in 'uapi/linux/types.h' so
it would be safe for normal program (other than perf).

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/bpf.c | 4 ++--
 tools/lib/bpf/bpf.h | 5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 88e6a46..e0dccea 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -57,7 +57,7 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size,
 
 int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 		     size_t insns_cnt, const char *license,
-		     u32 kern_version, char *log_buf, size_t log_buf_sz)
+		     __u32 kern_version, char *log_buf, size_t log_buf_sz)
 {
 	int fd;
 	union bpf_attr attr;
@@ -85,7 +85,7 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 }
 
 int bpf_map_update_elem(int fd, void *key, void *value,
-			u64 flags)
+			__u64 flags)
 {
 	union bpf_attr attr;
 
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 00cfeae..01a421a 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -8,6 +8,7 @@
 #ifndef __BPF_BPF_H
 #define __BPF_BPF_H
 
+#include <linux/types.h>
 #include <linux/bpf.h>
 
 int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
@@ -17,9 +18,9 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
 #define BPF_LOG_BUF_SIZE 65536
 int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 		     size_t insns_cnt, const char *license,
-		     u32 kern_version, char *log_buf,
+		     __u32 kern_version, char *log_buf,
 		     size_t log_buf_sz);
 
 int bpf_map_update_elem(int fd, void *key, void *value,
-			u64 flags);
+			__u64 flags);
 #endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 05/10] bpf tools: Support load different type of programs
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (3 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 04/10] bpf tools: Switch to uapi style type names Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Before this patch libbpf can only load program with type
BPF_PROG_TYPE_KPROBE program. To make libbpf useful in other scenarios,
this patch introduced bpf_program__set_type() and
bpf_object__set_type() which allows setting program type.

This changes doesn't break old API. The default program type is
BPF_PROG_TYPE_KPROBE. If caller wants to load program with other type,
one of these API should be called before bpf_object__load() or
in callback function of loader.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 43 ++++++++++++++++++++++++++++++++++++++-----
 tools/lib/bpf/libbpf.h | 16 ++++++++++++++++
 2 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 8334a5a..99be7f1 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -66,6 +66,7 @@ void libbpf_set_print(libbpf_print_fn_t warn,
 #define ERRNO_OFFSET(e)		((e) - __LIBBPF_ERRNO__START)
 #define ERRCODE_OFFSET(c)	ERRNO_OFFSET(LIBBPF_ERRNO__##c)
 #define NR_ERRNO	(__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
+#define BPF_PROG_TYPE_MAX	BPF_PROG_TYPE_SCHED_ACT
 
 static const char *libbpf_strerror_table[NR_ERRNO] = {
 	[ERRCODE_OFFSET(LIBELF)]	= "Something wrong in libelf",
@@ -161,6 +162,7 @@ struct bpf_program {
 	struct bpf_object *obj;
 	void *priv;
 	bpf_program_clear_priv_t clear_priv;
+	enum bpf_prog_type type;
 };
 
 struct bpf_map {
@@ -323,6 +325,7 @@ bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
 	obj->programs = progs;
 	obj->nr_programs = nr_progs + 1;
 	prog.obj = obj;
+	prog.type = BPF_PROG_TYPE_KPROBE;
 	progs[nr_progs] = prog;
 	return 0;
 }
@@ -871,7 +874,7 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 }
 
 static int
-load_program(struct bpf_insn *insns, int insns_cnt,
+load_program(struct bpf_insn *insns, int insns_cnt, enum bpf_prog_type type,
 	     char *license, u32 kern_version, int *pfd)
 {
 	int ret;
@@ -884,9 +887,8 @@ load_program(struct bpf_insn *insns, int insns_cnt,
 	if (!log_buf)
 		pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
 
-	ret = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
-			       insns_cnt, license, kern_version,
-			       log_buf, BPF_LOG_BUF_SIZE);
+	ret = bpf_load_program(type, insns, insns_cnt, license,
+			       kern_version, log_buf, BPF_LOG_BUF_SIZE);
 
 	if (ret >= 0) {
 		*pfd = ret;
@@ -945,7 +947,7 @@ bpf_program__load(struct bpf_program *prog,
 			pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
 				   prog->section_name, prog->instances.nr);
 		}
-		err = load_program(prog->insns, prog->insns_cnt,
+		err = load_program(prog->insns, prog->insns_cnt, prog->type,
 				   license, kern_version, &fd);
 		if (!err)
 			prog->instances.fds[0] = fd;
@@ -976,6 +978,7 @@ bpf_program__load(struct bpf_program *prog,
 
 		err = load_program(result.new_insn_ptr,
 				   result.new_insn_cnt,
+				   prog->type,
 				   license, kern_version, &fd);
 
 		if (err) {
@@ -1192,6 +1195,25 @@ bpf_object__get_kversion(struct bpf_object *obj)
 	return obj->kern_version;
 }
 
+int bpf_object__set_type(struct bpf_object *obj,
+			 enum bpf_prog_type type)
+{
+	struct bpf_program *prog;
+	int err;
+
+	if (!obj || type <= BPF_PROG_TYPE_UNSPEC ||
+	    type > BPF_PROG_TYPE_MAX)
+		return -EINVAL;
+
+	bpf_object__for_each_program(prog, obj) {
+		err = bpf_program__set_type(prog, type);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 struct bpf_program *
 bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
 {
@@ -1281,6 +1303,17 @@ int bpf_program__set_prep(struct bpf_program *prog, int nr_instances,
 	return 0;
 }
 
+int bpf_program__set_type(struct bpf_program *prog,
+			  enum bpf_prog_type type)
+{
+	if (!prog || type <= BPF_PROG_TYPE_UNSPEC ||
+	    type > BPF_PROG_TYPE_MAX)
+		return -EINVAL;
+
+	prog->type = type;
+	return 0;
+}
+
 int bpf_program__nth_fd(struct bpf_program *prog, int n)
 {
 	int fd;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index a51594c..c9d4130 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include <linux/err.h>
+#include <linux/bpf.h>
 
 enum libbpf_errno {
 	__LIBBPF_ERRNO__START = 4000,
@@ -58,6 +59,13 @@ int bpf_object__unload(struct bpf_object *obj);
 const char *bpf_object__get_name(struct bpf_object *obj);
 unsigned int bpf_object__get_kversion(struct bpf_object *obj);
 
+/*
+ * Set type of all programs in an object.
+ * See bpf_program__set_type().
+ */
+int bpf_object__set_type(struct bpf_object *obj,
+			 enum bpf_prog_type type);
+
 struct bpf_object *bpf_object__next(struct bpf_object *prev);
 #define bpf_object__for_each_safe(pos, tmp)			\
 	for ((pos) = bpf_object__next(NULL),		\
@@ -150,6 +158,14 @@ typedef int (*bpf_program_prep_t)(struct bpf_program *prog, int n,
 int bpf_program__set_prep(struct bpf_program *prog, int nr_instance,
 			  bpf_program_prep_t prep);
 
+/*
+ * Set type of a program. Default is BPF_PROG_TYPE_KPROBE.
+ * This function should be called before bpf_object__load()
+ * or in bpf_program_prep callback.
+ */
+int bpf_program__set_type(struct bpf_program *prog,
+			  enum bpf_prog_type type);
+
 int bpf_program__nth_fd(struct bpf_program *prog, int n);
 
 /*
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 06/10] bpf tools: Support new map operations
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (4 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 05/10] bpf tools: Support load different type of programs Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  6:06   ` Wangnan (F)
  2015-12-17  6:09   ` [PATCH v2 " Wang Nan
  2015-12-17  5:23 ` [PATCH 07/10] bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET Wang Nan
                   ` (4 subsequent siblings)
  10 siblings, 2 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Add bpf_map_lookup_elem(), bpf_map_delete_elem() and bpf_map_get_next_key()
to libbpf so it can issue all BPF map operations.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/bpf.c | 32 ++++++++++++++++++++++++++++++++
 tools/lib/bpf/bpf.h |  4 ++++
 2 files changed, 36 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index e0dccea..89c9d0b 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -97,3 +97,35 @@ int bpf_map_update_elem(int fd, void *key, void *value,
 
 	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
 }
+
+int bpf_map_lookup_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+		.value = ptr_to_u64(value),
+	};      
+
+	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
+}
+
+int bpf_map_delete_elem(int fd, void *key)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+	};
+
+	return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
+}
+
+int bpf_map_get_next_key(int fd, void *key, void *next_key)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+		.next_key = ptr_to_u64(next_key),
+	};
+
+	return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 01a421a..3d22048 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -23,4 +23,8 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 
 int bpf_map_update_elem(int fd, void *key, void *value,
 			__u64 flags);
+
+int bpf_map_lookup_elem(int fd, void *key, void *value);
+int bpf_map_delete_elem(int fd, void *key);
+int bpf_map_get_next_key(int fd, void *key, void *next_key);
 #endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 07/10] bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (5 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF Wang Nan
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan, Wang Nan

Commit b2197755b2633e164a439682fb05a9b5ea48f706 ("bpf: add support for
persistent maps/progs") introduces two new operations to both map and
program. This patch makes libbpf support it.

Signed-off-by: Wang Nan <wangnan0@hauwei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
---
 tools/lib/bpf/bpf.c | 21 +++++++++++++++++++++
 tools/lib/bpf/bpf.h |  3 +++
 2 files changed, 24 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 89c9d0b..5f174c6 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -129,3 +129,24 @@ int bpf_map_get_next_key(int fd, void *key, void *next_key)
 
 	return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
 }
+
+int bpf_pin_object(int fd, const char *pathname)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.pathname = ptr_to_u64((void *)pathname);
+	attr.bpf_fd = fd;
+
+	return sys_bpf(BPF_OBJ_PIN, &attr, sizeof(attr));
+}
+
+int bpf_get_pinned_object(const char *pathname)
+{
+	union bpf_attr attr;
+
+	bzero(&attr, sizeof(attr));
+	attr.pathname = ptr_to_u64((void *)pathname);
+
+	return sys_bpf(BPF_OBJ_GET, &attr, sizeof(attr));
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 3d22048..c9f1a1c 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -27,4 +27,7 @@ int bpf_map_update_elem(int fd, void *key, void *value,
 int bpf_map_lookup_elem(int fd, void *key, void *value);
 int bpf_map_delete_elem(int fd, void *key);
 int bpf_map_get_next_key(int fd, void *key, void *next_key);
+
+int bpf_pin_object(int fd, const char *pathname);
+int bpf_get_pinned_object(const char *pathname);
 #endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (6 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 07/10] bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17 23:11   ` Alexei Starovoitov
  2015-12-17  5:23 ` [PATCH 09/10] bpf samples: Uses libbpf in tools/lib to deal with BPF operations Wang Nan
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

We are going to uses libbpf to replace old libbpf.[ch] and
bpf_load.[ch]. This is the first patch of this work. In this patch,
several macros and helpers in libbpf.[ch] and bpf_load.[ch] are
merged into utils.[ch]. utils.[ch] utilizes libbpf in tools/lib to
deal with BPF related things. They would be compiled after Makefile
changes.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Alex Gartrell <agartrell@fb.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Brenden Blanco <bblanco@plumgrid.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Cc: Yang Shi <yang.shi@linaro.org>
---
 samples/bpf/include/linux/err.h |  56 ++++++++
 samples/bpf/utils.c             | 276 ++++++++++++++++++++++++++++++++++++++++
 samples/bpf/utils.h             | 217 +++++++++++++++++++++++++++++++
 3 files changed, 549 insertions(+)
 create mode 100644 samples/bpf/include/linux/err.h
 create mode 100644 samples/bpf/utils.c
 create mode 100644 samples/bpf/utils.h

diff --git a/samples/bpf/include/linux/err.h b/samples/bpf/include/linux/err.h
new file mode 100644
index 0000000..671b874
--- /dev/null
+++ b/samples/bpf/include/linux/err.h
@@ -0,0 +1,56 @@
+#ifndef __TOOLS_LINUX_ERR_H
+#define __TOOLS_LINUX_ERR_H
+
+#include <asm/errno.h>
+
+#ifndef __must_check
+# define __must_check
+#endif
+#ifndef __force
+# define __force
+#endif
+#ifndef unlikely
+# define unlikely(x) x
+#endif
+
+/*
+ * Original kernel header comment:
+ *
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a normal
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ *
+ * Userspace note:
+ * The same principle works for userspace, because 'error' pointers
+ * fall down to the unused hole far from user space, as described
+ * in Documentation/x86/x86_64/mm.txt for x86_64 arch:
+ *
+ * 0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm hole caused by [48:63] sign extension
+ * ffffffffffe00000 - ffffffffffffffff (=2 MB) unused hole
+ *
+ * It should be the same case for other architectures, because
+ * this code is used in generic kernel code.
+ */
+#define MAX_ERRNO	4095
+
+#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
+
+static inline void * __must_check ERR_PTR(long error_)
+{
+	return (void *) error_;
+}
+
+static inline long __must_check PTR_ERR(__force const void *ptr)
+{
+	return (long) ptr;
+}
+
+static inline bool __must_check IS_ERR(__force const void *ptr)
+{
+	return IS_ERR_VALUE((unsigned long)ptr);
+}
+
+#endif /* _LINUX_ERR_H */
diff --git a/samples/bpf/utils.c b/samples/bpf/utils.c
new file mode 100644
index 0000000..73262a9
--- /dev/null
+++ b/samples/bpf/utils.c
@@ -0,0 +1,276 @@
+/* eBPF mini library */
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <linux/unistd.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <linux/netlink.h>
+#include <linux/bpf.h>
+#include <errno.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <linux/if_packet.h>
+#include <arpa/inet.h>
+#include <linux/perf_event.h>
+#include "utils.h"
+
+#define DEBUGFS "/sys/kernel/debug/tracing/"
+
+int open_raw_sock(const char *name)
+{
+	struct sockaddr_ll sll;
+	int sock;
+
+	sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, htons(ETH_P_ALL));
+	if (sock < 0) {
+		printf("cannot create raw socket\n");
+		return -1;
+	}
+
+	memset(&sll, 0, sizeof(sll));
+	sll.sll_family = AF_PACKET;
+	sll.sll_ifindex = if_nametoindex(name);
+	sll.sll_protocol = htons(ETH_P_ALL);
+	if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
+		printf("bind to %s: %s\n", name, strerror(errno));
+		close(sock);
+		return -1;
+	}
+
+	return sock;
+}
+
+void read_trace_pipe(void)
+{
+	int trace_fd;
+
+	trace_fd = open(DEBUGFS "trace_pipe", O_RDONLY, 0);
+	if (trace_fd < 0)
+		return;
+
+	while (1) {
+		static char buf[4096];
+		ssize_t sz;
+
+		sz = read(trace_fd, buf, sizeof(buf));
+		if (sz > 0) {
+			buf[sz] = 0;
+			puts(buf);
+		}
+	}
+}
+
+int perf_event_open(struct perf_event_attr *attr, int pid, int cpu,
+		    int group_fd, unsigned long flags)
+{
+	return syscall(__NR_perf_event_open, attr, pid, cpu,
+		       group_fd, flags);
+}
+
+static int prog_load_prep(struct bpf_program *prog, int n,
+			  struct bpf_insn *insns, int insns_cnt,
+			  struct bpf_prog_prep_result *res)
+{
+	enum bpf_prog_type prog_type;
+	int is_socket, is_kprobe, is_kretprobe;
+	const char *event = bpf_program__title(prog, false);
+
+	LIBBPF_PTR_ASSERT(event, return -1);
+
+	is_socket = strncmp(event, "socket", 6) == 0;
+	is_kprobe = strncmp(event, "kprobe/", 7) == 0;
+	is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
+
+	if (is_socket) {
+		prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
+	} else if (is_kprobe || is_kretprobe) {
+		prog_type = BPF_PROG_TYPE_KPROBE;
+	} else {
+		fprintf(stderr, "Unknown event '%s'\n", event);
+		return -1;
+	}
+
+	LIBBPF_ASSERT(bpf_program__set_type(prog, prog_type), return -1);
+	res->new_insn_ptr = insns;
+	res->new_insn_cnt = insns_cnt;
+	return 0;
+}
+
+static int populate_prog_array(int map_fd, struct bpf_object *obj)
+{
+	struct bpf_program *prog;
+
+	if (map_fd < 0) {
+		fprintf(stderr, "Invalid map fd\n");
+		return -1;
+	}
+
+	bpf_object__for_each_program(prog, obj) {
+		const char *event = bpf_program__title(prog, false);
+		int ind, prog_fd;
+		const char *ptr;
+
+		LIBBPF_PTR_ASSERT(event, return -1);
+		ptr = event + strlen(event) - 1;
+		while (isdigit(*ptr))
+			ptr--;
+		ptr++;
+		if (!isdigit(*ptr)) {
+			fprintf(stderr, "Invalid event: %s\n", event);
+			return -1;
+		}
+
+		ind = atoi(ptr);
+
+		__LIBBPF_ASSERT(prog_fd = bpf_program__nth_fd(prog, 0),
+				>= 0, return -1);
+		LIBBPF_ASSERT(bpf_map_update_elem(map_fd, &ind,
+						  &prog_fd, BPF_ANY),
+			      return -1);
+	}
+	return 0;
+}
+
+static int create_kprobes(int fd, const char *event, bool is_kprobe)
+{
+	char buf[256];
+	int efd, err, id;
+	struct perf_event_attr attr = {};
+
+	if (isdigit(event[0]))
+		return 0;
+
+	attr.type = PERF_TYPE_TRACEPOINT;
+	attr.sample_type = PERF_SAMPLE_RAW;
+	attr.sample_period = 1;
+	attr.wakeup_events = 1;
+
+	snprintf(buf, sizeof(buf),
+		 "echo '%c:%s %s' >> /sys/kernel/debug/tracing/kprobe_events",
+		 is_kprobe ? 'p' : 'r', event, event);
+
+	err = system(buf);
+	if (err < 0) {
+		fprintf(stderr, "failed to create kprobe '%s' error '%s'\n",
+				event, strerror(errno));
+		return -1;
+	}
+
+	strcpy(buf, DEBUGFS);
+	strcat(buf, "events/kprobes/");
+	strcat(buf, event);
+	strcat(buf, "/id");
+
+	efd = open(buf, O_RDONLY, 0);
+	if (efd < 0) {
+		fprintf(stderr, "failed to open event %s\n", event);
+		return -1;
+	}
+
+	err = read(efd, buf, sizeof(buf));
+	if (err < 0 || err >= sizeof(buf)) {
+		fprintf(stderr, "read from '%s' failed '%s'\n",
+			event, strerror(errno));
+		return -1;
+	}
+
+	close(efd);
+
+	buf[err] = 0;
+	id = atoi(buf);
+	attr.config = id;
+
+	efd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
+	if (efd < 0) {
+		fprintf(stderr, "event %d fd %d err %s\n", id, efd,
+			strerror(errno));
+		return -1;
+	}
+
+	ioctl(efd, PERF_EVENT_IOC_ENABLE, 0);
+	ioctl(efd, PERF_EVENT_IOC_SET_BPF, fd);
+	return 0;
+}
+
+struct bpf_object *load_bpf_file(char *path)
+{
+	struct bpf_program *prog;
+	struct bpf_object *obj;
+	struct bpf_map *map;
+	int err;
+
+	/* clear all kprobes */
+	err = system("echo \"\" > /sys/kernel/debug/tracing/kprobe_events");
+	if (err)
+		fprintf(stderr, "WARNING: clear kprobe_events failed: %s\n", strerror(errno));
+
+	LIBBPF_PTR_ASSERT(obj = bpf_object__open(path), return NULL);
+
+	bpf_object__for_each_program(prog, obj)
+		LIBBPF_ASSERT(bpf_program__set_prep(prog, 1, prog_load_prep),
+			      goto errout);
+
+	LIBBPF_ASSERT(bpf_object__load(obj), goto errout);
+
+	bpf_map__for_each(map, obj) {
+		struct bpf_map_def def;
+
+		LIBBPF_ASSERT(bpf_map__get_def(map, &def), goto errout);
+		if (def.type == BPF_MAP_TYPE_PROG_ARRAY) {
+			if (populate_prog_array(bpf_map__get_fd(map), obj)) {
+				fprintf(stderr, "failed to populate program array\n");
+				goto errout;
+			}
+		}
+	}
+
+	bpf_object__for_each_program(prog, obj) {
+		const char *event = bpf_program__title(prog, false);
+		int fd, err;
+
+		LIBBPF_PTR_ASSERT(event, goto errout);
+		__LIBBPF_ASSERT(fd = bpf_program__nth_fd(prog, 0),
+				>= 0,
+				goto errout);
+
+		if (strncmp(event, "kprobe/", 7) == 0)
+			err = create_kprobes(fd, event + 7, true);
+		else if (strncmp(event, "kretprobe/", 10) == 0)
+			err = create_kprobes(fd, event + 10, false);
+
+		if (err) {
+			fprintf(stderr, "failed to create kprobes\n");
+			goto errout;
+		}
+	}
+
+	return obj;
+errout:
+	bpf_object__close(obj);
+	return NULL;
+}
+
+int get_prog_fd(struct bpf_object *obj, int idx)
+{
+	int i = 0;
+	struct bpf_program *prog;
+
+	bpf_object__for_each_program(prog, obj)
+		if (i++ == idx)
+			return bpf_program__nth_fd(prog, 0);
+	return -1;
+}
+
+int get_map_fd(struct bpf_object *obj, int idx)
+{
+	int i = 0;
+	struct bpf_map *map;
+
+	bpf_map__for_each(map, obj)
+		if (i++ == idx)
+			return bpf_map__get_fd(map);
+	return -1;
+}
diff --git a/samples/bpf/utils.h b/samples/bpf/utils.h
new file mode 100644
index 0000000..5962a68
--- /dev/null
+++ b/samples/bpf/utils.h
@@ -0,0 +1,217 @@
+#ifndef __SAMPELS_UTILS_H
+#define __SAMPELS_UTILS_H
+
+#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
+
+/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
+
+#define BPF_ALU64_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define BPF_ALU32_REG(OP, DST, SRC)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
+
+#define BPF_ALU64_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+#define BPF_ALU32_IMM(OP, DST, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Short form of mov, dst_reg = src_reg */
+
+#define BPF_MOV64_REG(DST, SRC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define BPF_MOV32_REG(DST, SRC)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU | BPF_MOV | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+/* Short form of mov, dst_reg = imm32 */
+
+#define BPF_MOV64_IMM(DST, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
+#define BPF_LD_IMM64(DST, IMM)					\
+	BPF_LD_IMM64_RAW(DST, 0, IMM)
+
+#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_DW | BPF_IMM,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = 0,					\
+		.imm   = (__u32) (IMM) }),			\
+	((struct bpf_insn) {					\
+		.code  = 0, /* zero is reserved opcode */	\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = ((__u64) (IMM)) >> 32 })
+
+#ifndef BPF_PSEUDO_MAP_FD
+# define BPF_PSEUDO_MAP_FD	1
+#endif
+
+/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
+#define BPF_LD_MAP_FD(DST, MAP_FD)				\
+	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
+
+
+/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
+
+#define BPF_LD_ABS(SIZE, IMM)					\
+	((struct bpf_insn) {					\
+		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = IMM })
+
+/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
+
+#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
+
+#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
+	((struct bpf_insn) {					\
+		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
+
+#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
+
+#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = 0 })
+
+/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
+
+#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
+		.dst_reg = DST,					\
+		.src_reg = 0,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Raw code statement block */
+
+#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
+	((struct bpf_insn) {					\
+		.code  = CODE,					\
+		.dst_reg = DST,					\
+		.src_reg = SRC,					\
+		.off   = OFF,					\
+		.imm   = IMM })
+
+/* Program exit */
+
+#define BPF_EXIT_INSN()						\
+	((struct bpf_insn) {					\
+		.code  = BPF_JMP | BPF_EXIT,			\
+		.dst_reg = 0,					\
+		.src_reg = 0,					\
+		.off   = 0,					\
+		.imm   = 0 })
+
+#define __LIBBPF_ASSERT(stat, cond, ret) do {	\
+	char ___errbuf[256];			\
+	int ___err = stat;			\
+						\
+	if ((___err) cond)			\
+		break;				\
+	libbpf_strerror(___err, ___errbuf, sizeof(___errbuf));\
+	fprintf(stderr, "libbpf error: %s\n", ___errbuf);\
+	ret;					\
+} while(0)
+
+#define __LIBBPF_PTR_ASSERT(stat, cond, ret) do {	\
+	const void *___ptr = stat;			\
+							\
+	if (!IS_ERR(___ptr) && ___ptr)			\
+		break;					\
+	if (!___ptr)					\
+		___ptr = ERR_PTR(-EEXIST);		\
+	LIBBPF_ASSERT(PTR_ERR(___ptr), ret);		\
+} while(0)
+
+#define LIBBPF_ASSERT(stat, ret) __LIBBPF_ASSERT(stat, == 0, ret)
+#define LIBBPF_PTR_ASSERT(stat, ret) __LIBBPF_PTR_ASSERT(stat, == 0, ret)
+
+/* create RAW socket and bind to interface 'name' */
+int open_raw_sock(const char *name);
+void read_trace_pipe(void);
+
+struct perf_event_attr;
+int perf_event_open(struct perf_event_attr *attr, int pid, int cpu,
+		    int group_fd, unsigned long flags);
+
+int prog_load_prepare(struct bpf_program *prog, int n,
+		      struct bpf_insn *insns, int insns_cnt,
+		      struct bpf_prog_prep_result *res);
+
+struct bpf_object *load_bpf_file(char *path);
+int get_prog_fd(struct bpf_object *obj, int idx);
+int get_map_fd(struct bpf_object *obj, int idx);
+#endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 09/10] bpf samples: Uses libbpf in tools/lib to deal with BPF operations
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (7 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  5:23 ` [PATCH 10/10] bpf samples: Remove old BPF helpers Wang Nan
  2015-12-17  6:38 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Daniel Wagner
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Since we already have libbpf in tools/lib, there's no need to maintain
a duplicate BPF loading and operations library in samples.

This patch utilises previous introduced utils.[ch], which calls libbpf
to do these work.

The main changing in this relative large patch is very simple:

 1. Makefile modification, makes all hostprogs depend on libbpf.a.
    Add include and library searching patch and rules for linker.
    Remove old bpf_load.o and libbpf.o, replaces them with utils.o

 2. Make sure there are correct 'version' section so the BPF source
    files can be loaded by libbpf.

 3. Uses API provided by utils.h and libbpf.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Alex Gartrell <agartrell@fb.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Brenden Blanco <bblanco@plumgrid.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Cc: Yang Shi <yang.shi@linaro.org>
---
 samples/bpf/Makefile            | 65 ++++++++++++++++++---------------
 samples/bpf/fds_example.c       | 26 +++++++-------
 samples/bpf/lathist_user.c      | 13 ++++---
 samples/bpf/sock_example.c      | 13 +++----
 samples/bpf/sockex1_kern.c      |  2 ++
 samples/bpf/sockex1_user.c      | 27 ++++++++------
 samples/bpf/sockex2_kern.c      |  2 ++
 samples/bpf/sockex2_user.c      | 26 ++++++++------
 samples/bpf/sockex3_kern.c      |  2 ++
 samples/bpf/sockex3_user.c      | 23 +++++++-----
 samples/bpf/test_maps.c         | 80 ++++++++++++++++++++---------------------
 samples/bpf/test_verifier.c     | 13 ++++---
 samples/bpf/trace_output_user.c | 17 +++++----
 samples/bpf/tracex1_user.c      |  9 +++--
 samples/bpf/tracex2_user.c      | 31 +++++++++-------
 samples/bpf/tracex3_user.c      | 15 ++++----
 samples/bpf/tracex4_user.c      | 15 ++++----
 samples/bpf/tracex5_user.c      |  9 +++--
 samples/bpf/tracex6_user.c      | 16 ++++-----
 19 files changed, 221 insertions(+), 183 deletions(-)

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index edd638b..edb7c04 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -1,6 +1,20 @@
 # kbuild trick to avoid linker error. Can be omitted if a module is built.
 obj- := dummy.o
 
+INC_DIR = $(src)/include
+TOOLS_DIR = $(realpath $(srctree))/tools
+TOOLS_LIB_DIR = $(TOOLS_DIR)/lib
+LIBBPF_DIR = $(TOOLS_LIB_DIR)/bpf
+
+$(obj)/libbpf/libbpf.a:
+	$(Q)mkdir -p $(obj)/libbpf
+	$(MAKE) -C $(LIBBPF_DIR) O=$(realpath $(obj))/libbpf CFLAGS= LDFLAGS= V=1 $(realpath $(obj))/libbpf/libbpf.a
+
+HOSTCFLAGS += -I$(TOOLS_LIB_DIR) -I$(INC_DIR)
+HOSTLDFLAGS += -L$(obj)/libbpf
+HOSTCFLAGS += -I$(INC_DIR) -I$(TOOLS_LIB_DIR)
+HOST_LOADLIBES += -lelf -lbpf
+
 # List of programs to build
 hostprogs-y := test_verifier test_maps
 hostprogs-y += sock_example
@@ -17,21 +31,27 @@ hostprogs-y += tracex6
 hostprogs-y += trace_output
 hostprogs-y += lathist
 
-test_verifier-objs := test_verifier.o libbpf.o
-test_maps-objs := test_maps.o libbpf.o
-sock_example-objs := sock_example.o libbpf.o
-fds_example-objs := bpf_load.o libbpf.o fds_example.o
-sockex1-objs := bpf_load.o libbpf.o sockex1_user.o
-sockex2-objs := bpf_load.o libbpf.o sockex2_user.o
-sockex3-objs := bpf_load.o libbpf.o sockex3_user.o
-tracex1-objs := bpf_load.o libbpf.o tracex1_user.o
-tracex2-objs := bpf_load.o libbpf.o tracex2_user.o
-tracex3-objs := bpf_load.o libbpf.o tracex3_user.o
-tracex4-objs := bpf_load.o libbpf.o tracex4_user.o
-tracex5-objs := bpf_load.o libbpf.o tracex5_user.o
-tracex6-objs := bpf_load.o libbpf.o tracex6_user.o
-trace_output-objs := bpf_load.o libbpf.o trace_output_user.o
-lathist-objs := bpf_load.o libbpf.o lathist_user.o
+test_verifier-objs := test_verifier.o
+test_maps-objs := test_maps.o
+sock_example-objs := sock_example.o utils.o
+fds_example-objs := utils.o fds_example.o
+sockex1-objs := utils.o sockex1_user.o
+sockex2-objs := utils.o sockex2_user.o
+sockex3-objs := utils.o sockex3_user.o
+tracex1-objs := utils.o tracex1_user.o
+tracex2-objs := utils.o tracex2_user.o
+tracex3-objs := utils.o tracex3_user.o
+tracex4-objs := utils.o tracex4_user.o
+tracex5-objs := utils.o tracex5_user.o
+tracex6-objs := utils.o tracex6_user.o
+trace_output-objs := utils.o trace_output_user.o
+lathist-objs := utils.o lathist_user.o
+
+define add_depend
+$(foreach m, $(notdir $1), \
+	$(eval $(obj)/$m: $(obj)/libbpf/libbpf.a))
+endef
+$(call add_depend, $(hostprogs-y))
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -50,19 +70,8 @@ always += lathist_kern.o
 
 HOSTCFLAGS += -I$(objtree)/usr/include
 
-HOSTCFLAGS_bpf_load.o += -I$(objtree)/usr/include -Wno-unused-variable
-HOSTLOADLIBES_fds_example += -lelf
-HOSTLOADLIBES_sockex1 += -lelf
-HOSTLOADLIBES_sockex2 += -lelf
-HOSTLOADLIBES_sockex3 += -lelf
-HOSTLOADLIBES_tracex1 += -lelf
-HOSTLOADLIBES_tracex2 += -lelf
-HOSTLOADLIBES_tracex3 += -lelf
-HOSTLOADLIBES_tracex4 += -lelf -lrt
-HOSTLOADLIBES_tracex5 += -lelf
-HOSTLOADLIBES_tracex6 += -lelf
-HOSTLOADLIBES_trace_output += -lelf -lrt
-HOSTLOADLIBES_lathist += -lelf
+HOSTLOADLIBES_tracex4 += -lrt
+HOSTLOADLIBES_trace_output += -lrt
 
 # point this to your LLVM backend with bpf support
 LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc
diff --git a/samples/bpf/fds_example.c b/samples/bpf/fds_example.c
index e2fd16c..bdcfce0 100644
--- a/samples/bpf/fds_example.c
+++ b/samples/bpf/fds_example.c
@@ -12,8 +12,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
-#include "bpf_load.h"
-#include "libbpf.h"
+#include "utils.h"
 
 #define BPF_F_PIN	(1 << 0)
 #define BPF_F_GET	(1 << 1)
@@ -55,11 +54,14 @@ static int bpf_prog_create(const char *object)
 	};
 
 	if (object) {
-		assert(!load_bpf_file((char *)object));
-		return prog_fd[0];
+		struct bpf_object *obj = load_bpf_file((char *)object);
+
+		assert(obj);
+		return get_prog_fd(obj, 0);
 	} else {
-		return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,
-				     insns, sizeof(insns), "GPL", 0);
+		return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER,
+					insns, sizeof(insns) / sizeof(insns[0]),
+					"GPL", 0, NULL, 0);
 	}
 }
 
@@ -73,22 +75,22 @@ static int bpf_do_map(const char *file, uint32_t flags, uint32_t key,
 		printf("bpf: map fd:%d (%s)\n", fd, strerror(errno));
 		assert(fd > 0);
 
-		ret = bpf_obj_pin(fd, file);
+		ret = bpf_pin_object(fd, file);
 		printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
 		assert(ret == 0);
 	} else {
-		fd = bpf_obj_get(file);
+		fd = bpf_get_pinned_object(file);
 		printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
 		assert(fd > 0);
 	}
 
 	if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) {
-		ret = bpf_update_elem(fd, &key, &value, 0);
+		ret = bpf_map_update_elem(fd, &key, &value, 0);
 		printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value,
 		       ret, strerror(errno));
 		assert(ret == 0);
 	} else if (flags & BPF_F_KEY) {
-		ret = bpf_lookup_elem(fd, &key, &value);
+		ret = bpf_map_lookup_elem(fd, &key, &value);
 		printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value,
 		       ret, strerror(errno));
 		assert(ret == 0);
@@ -106,11 +108,11 @@ static int bpf_do_prog(const char *file, uint32_t flags, const char *object)
 		printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno));
 		assert(fd > 0);
 
-		ret = bpf_obj_pin(fd, file);
+		ret = bpf_pin_object(fd, file);
 		printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
 		assert(ret == 0);
 	} else {
-		fd = bpf_obj_get(file);
+		fd = bpf_get_pinned_object(file);
 		printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
 		assert(fd > 0);
 	}
diff --git a/samples/bpf/lathist_user.c b/samples/bpf/lathist_user.c
index 65da8c1..9160af8 100644
--- a/samples/bpf/lathist_user.c
+++ b/samples/bpf/lathist_user.c
@@ -10,8 +10,7 @@
 #include <stdlib.h>
 #include <signal.h>
 #include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 #define MAX_ENTRIES	20
 #define MAX_CPU		4
@@ -73,7 +72,7 @@ static void get_data(int fd)
 	for (c = 0; c < MAX_CPU; c++) {
 		for (i = 0; i < MAX_ENTRIES; i++) {
 			key = c * MAX_ENTRIES + i;
-			bpf_lookup_elem(fd, &key, &value);
+			bpf_map_lookup_elem(fd, &key, &value);
 
 			cpu_hist[c].data[i] = value;
 			if (value > cpu_hist[c].max)
@@ -85,16 +84,16 @@ static void get_data(int fd)
 int main(int argc, char **argv)
 {
 	char filename[256];
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
 	while (1) {
-		get_data(map_fd[1]);
+		get_data(get_map_fd(obj, 1));
 		print_hist();
 		sleep(5);
 	}
diff --git a/samples/bpf/sock_example.c b/samples/bpf/sock_example.c
index a0ce251..a6a875f 100644
--- a/samples/bpf/sock_example.c
+++ b/samples/bpf/sock_example.c
@@ -26,7 +26,7 @@
 #include <linux/if_ether.h>
 #include <linux/ip.h>
 #include <stddef.h>
-#include "libbpf.h"
+#include "utils.h"
 
 static int test_sock(void)
 {
@@ -55,8 +55,9 @@ static int test_sock(void)
 		BPF_EXIT_INSN(),
 	};
 
-	prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog),
-				"GPL", 0);
+	prog_fd = bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog,
+				   sizeof(prog) / sizeof(prog[0]),
+				   "GPL", 0, NULL, 0);
 	if (prog_fd < 0) {
 		printf("failed to load prog '%s'\n", strerror(errno));
 		goto cleanup;
@@ -72,13 +73,13 @@ static int test_sock(void)
 
 	for (i = 0; i < 10; i++) {
 		key = IPPROTO_TCP;
-		assert(bpf_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
 
 		key = IPPROTO_UDP;
-		assert(bpf_lookup_elem(map_fd, &key, &udp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);
 
 		key = IPPROTO_ICMP;
-		assert(bpf_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
 
 		printf("TCP %lld UDP %lld ICMP %lld packets\n",
 		       tcp_cnt, udp_cnt, icmp_cnt);
diff --git a/samples/bpf/sockex1_kern.c b/samples/bpf/sockex1_kern.c
index ed18e9a..0ab3d9a 100644
--- a/samples/bpf/sockex1_kern.c
+++ b/samples/bpf/sockex1_kern.c
@@ -2,6 +2,7 @@
 #include <uapi/linux/if_ether.h>
 #include <uapi/linux/if_packet.h>
 #include <uapi/linux/ip.h>
+#include <linux/version.h>
 #include "bpf_helpers.h"
 
 struct bpf_map_def SEC("maps") my_map = {
@@ -27,3 +28,4 @@ int bpf_prog1(struct __sk_buff *skb)
 	return 0;
 }
 char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/sockex1_user.c b/samples/bpf/sockex1_user.c
index 678ce46..d1ece36 100644
--- a/samples/bpf/sockex1_user.c
+++ b/samples/bpf/sockex1_user.c
@@ -1,28 +1,33 @@
 #include <stdio.h>
 #include <assert.h>
-#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
 #include <unistd.h>
 #include <arpa/inet.h>
+#include "utils.h"
 
 int main(int ac, char **argv)
 {
 	char filename[256];
 	FILE *f;
-	int i, sock;
+	int i, sock, map_fd, prog_fd;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
+		return 1;
+
+	map_fd = get_map_fd(obj, 0);
+	prog_fd = get_prog_fd(obj, 0);
+	if (map_fd < 0 || prog_fd < 0) {
+		fprintf(stderr, "failed to get file descriptor\n");
 		return 1;
 	}
 
 	sock = open_raw_sock("lo");
 
-	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd,
-			  sizeof(prog_fd[0])) == 0);
+	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
+			  sizeof(prog_fd)) == 0);
 
 	f = popen("ping -c5 localhost", "r");
 	(void) f;
@@ -32,13 +37,13 @@ int main(int ac, char **argv)
 		int key;
 
 		key = IPPROTO_TCP;
-		assert(bpf_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
 
 		key = IPPROTO_UDP;
-		assert(bpf_lookup_elem(map_fd[0], &key, &udp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);
 
 		key = IPPROTO_ICMP;
-		assert(bpf_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0);
+		assert(bpf_map_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
 
 		printf("TCP %lld UDP %lld ICMP %lld bytes\n",
 		       tcp_cnt, udp_cnt, icmp_cnt);
diff --git a/samples/bpf/sockex2_kern.c b/samples/bpf/sockex2_kern.c
index ba0e177..46e2e77 100644
--- a/samples/bpf/sockex2_kern.c
+++ b/samples/bpf/sockex2_kern.c
@@ -6,6 +6,7 @@
 #include <uapi/linux/ip.h>
 #include <uapi/linux/ipv6.h>
 #include <uapi/linux/if_tunnel.h>
+#include <linux/version.h>
 #define IP_MF		0x2000
 #define IP_OFFSET	0x1FFF
 
@@ -219,3 +220,4 @@ int bpf_prog2(struct __sk_buff *skb)
 }
 
 char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/sockex2_user.c b/samples/bpf/sockex2_user.c
index 29a276d..3df6442 100644
--- a/samples/bpf/sockex2_user.c
+++ b/samples/bpf/sockex2_user.c
@@ -1,10 +1,9 @@
 #include <stdio.h>
 #include <assert.h>
-#include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
 #include <unistd.h>
 #include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include "utils.h"
 
 struct pair {
 	__u64 packets;
@@ -15,19 +14,26 @@ int main(int ac, char **argv)
 {
 	char filename[256];
 	FILE *f;
-	int i, sock;
+	int i, sock, map_fd, prog_fd;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
+		return 1;
+
+	map_fd = get_map_fd(obj, 0);
+	prog_fd = get_prog_fd(obj, 0);
+	if (map_fd < 0 || prog_fd < 0) {
+		fprintf(stderr, "failed to get file descriptor\n");
 		return 1;
 	}
 
 	sock = open_raw_sock("lo");
 
-	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, prog_fd,
-			  sizeof(prog_fd[0])) == 0);
+	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
+			  sizeof(prog_fd)) == 0);
 
 	f = popen("ping -c5 localhost", "r");
 	(void) f;
@@ -36,8 +42,8 @@ int main(int ac, char **argv)
 		int key = 0, next_key;
 		struct pair value;
 
-		while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
-			bpf_lookup_elem(map_fd[0], &next_key, &value);
+		while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+			bpf_map_lookup_elem(map_fd, &next_key, &value);
 			printf("ip %s bytes %lld packets %lld\n",
 			       inet_ntoa((struct in_addr){htonl(next_key)}),
 			       value.bytes, value.packets);
diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index 41ae2fd..6ac0d17 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -13,6 +13,7 @@
 #include <uapi/linux/ipv6.h>
 #include <uapi/linux/if_tunnel.h>
 #include <uapi/linux/mpls.h>
+#include <linux/version.h>
 #define IP_MF		0x2000
 #define IP_OFFSET	0x1FFF
 
@@ -288,3 +289,4 @@ int main_prog(struct __sk_buff *skb)
 }
 
 char _license[] SEC("license") = "GPL";
+int _version SEC("version") = LINUX_VERSION_CODE;
diff --git a/samples/bpf/sockex3_user.c b/samples/bpf/sockex3_user.c
index 2617772..99a7126 100644
--- a/samples/bpf/sockex3_user.c
+++ b/samples/bpf/sockex3_user.c
@@ -1,10 +1,10 @@
 #include <stdio.h>
 #include <assert.h>
 #include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
 #include <unistd.h>
 #include <arpa/inet.h>
+#include <bpf/bpf.h>
+#include "utils.h"
 
 struct flow_keys {
 	__be32 src;
@@ -25,18 +25,25 @@ int main(int argc, char **argv)
 {
 	char filename[256];
 	FILE *f;
-	int i, sock;
+	int i, sock, map_fd, prog_fd;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
+		return 1;
+
+	map_fd = get_map_fd(obj, 2);
+	prog_fd = get_prog_fd(obj, 4);
+	if (map_fd < 0 || prog_fd < 0) {
+		fprintf(stderr, "failed to get file descriptor\n");
 		return 1;
 	}
 
 	sock = open_raw_sock("lo");
 
-	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd[4],
+	assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
 			  sizeof(__u32)) == 0);
 
 	if (argc > 1)
@@ -51,8 +58,8 @@ int main(int argc, char **argv)
 
 		sleep(1);
 		printf("IP     src.port -> dst.port               bytes      packets\n");
-		while (bpf_get_next_key(map_fd[2], &key, &next_key) == 0) {
-			bpf_lookup_elem(map_fd[2], &next_key, &value);
+		while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+			bpf_map_lookup_elem(map_fd, &next_key, &value);
 			printf("%s.%05d -> %s.%05d %12lld %12lld\n",
 			       inet_ntoa((struct in_addr){htonl(next_key.src)}),
 			       next_key.port16[0],
diff --git a/samples/bpf/test_maps.c b/samples/bpf/test_maps.c
index 6299ee9..435d55e 100644
--- a/samples/bpf/test_maps.c
+++ b/samples/bpf/test_maps.c
@@ -15,7 +15,7 @@
 #include <assert.h>
 #include <sys/wait.h>
 #include <stdlib.h>
-#include "libbpf.h"
+#include "utils.h"
 
 /* sanity tests for map API */
 static void test_hashmap_sanity(int i, void *data)
@@ -32,59 +32,59 @@ static void test_hashmap_sanity(int i, void *data)
 	key = 1;
 	value = 1234;
 	/* insert key=1 element */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
 
 	value = 0;
 	/* BPF_NOEXIST means: add new element if it doesn't exist */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
 	       /* key=1 already exists */
 	       errno == EEXIST);
 
-	assert(bpf_update_elem(map_fd, &key, &value, -1) == -1 && errno == EINVAL);
+	assert(bpf_map_update_elem(map_fd, &key, &value, -1) == -1 && errno == EINVAL);
 
 	/* check that key=1 can be found */
-	assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
 
 	key = 2;
 	/* check that key=2 is not found */
-	assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
 
 	/* BPF_EXIST means: update existing element */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
 	       /* key=2 is not there */
 	       errno == ENOENT);
 
 	/* insert key=2 element */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
 
 	/* key=1 and key=2 were inserted, check that key=0 cannot be inserted
 	 * due to max_entries limit
 	 */
 	key = 0;
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
 	       errno == E2BIG);
 
 	/* check that key = 0 doesn't exist */
-	assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
+	assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
 
 	/* iterate over two elements */
-	assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 &&
+	assert(bpf_map_get_next_key(map_fd, &key, &next_key) == 0 &&
 	       (next_key == 1 || next_key == 2));
-	assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 &&
+	assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == 0 &&
 	       (next_key == 1 || next_key == 2));
-	assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 &&
+	assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == -1 &&
 	       errno == ENOENT);
 
 	/* delete both elements */
 	key = 1;
-	assert(bpf_delete_elem(map_fd, &key) == 0);
+	assert(bpf_map_delete_elem(map_fd, &key) == 0);
 	key = 2;
-	assert(bpf_delete_elem(map_fd, &key) == 0);
-	assert(bpf_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
+	assert(bpf_map_delete_elem(map_fd, &key) == 0);
+	assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == ENOENT);
 
 	key = 0;
 	/* check that map is empty */
-	assert(bpf_get_next_key(map_fd, &key, &next_key) == -1 &&
+	assert(bpf_map_get_next_key(map_fd, &key, &next_key) == -1 &&
 	       errno == ENOENT);
 	close(map_fd);
 }
@@ -103,41 +103,41 @@ static void test_arraymap_sanity(int i, void *data)
 	key = 1;
 	value = 1234;
 	/* insert key=1 element */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_ANY) == 0);
 
 	value = 0;
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
 	       errno == EEXIST);
 
 	/* check that key=1 can be found */
-	assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 1234);
 
 	key = 0;
 	/* check that key=0 is also found and zero initialized */
-	assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
 
 
 	/* key=0 and key=1 were inserted, check that key=2 cannot be inserted
 	 * due to max_entries limit
 	 */
 	key = 2;
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_EXIST) == -1 &&
 	       errno == E2BIG);
 
 	/* check that key = 2 doesn't exist */
-	assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
 
 	/* iterate over two elements */
-	assert(bpf_get_next_key(map_fd, &key, &next_key) == 0 &&
+	assert(bpf_map_get_next_key(map_fd, &key, &next_key) == 0 &&
 	       next_key == 0);
-	assert(bpf_get_next_key(map_fd, &next_key, &next_key) == 0 &&
+	assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == 0 &&
 	       next_key == 1);
-	assert(bpf_get_next_key(map_fd, &next_key, &next_key) == -1 &&
+	assert(bpf_map_get_next_key(map_fd, &next_key, &next_key) == -1 &&
 	       errno == ENOENT);
 
 	/* delete shouldn't succeed */
 	key = 1;
-	assert(bpf_delete_elem(map_fd, &key) == -1 && errno == EINVAL);
+	assert(bpf_map_delete_elem(map_fd, &key) == -1 && errno == EINVAL);
 
 	close(map_fd);
 }
@@ -163,21 +163,21 @@ static void test_map_large(void)
 	for (i = 0; i < MAP_SIZE; i++) {
 		key = (struct bigkey) {.c = i};
 		value = i;
-		assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+		assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
 	}
 	key.c = -1;
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
 	       errno == E2BIG);
 
 	/* iterate through all elements */
 	for (i = 0; i < MAP_SIZE; i++)
-		assert(bpf_get_next_key(map_fd, &key, &key) == 0);
-	assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+		assert(bpf_map_get_next_key(map_fd, &key, &key) == 0);
+	assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
 
 	key.c = 0;
-	assert(bpf_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 && value == 0);
 	key.a = 1;
-	assert(bpf_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
+	assert(bpf_map_lookup_elem(map_fd, &key, &value) == -1 && errno == ENOENT);
 
 	close(map_fd);
 }
@@ -225,9 +225,9 @@ static void do_work(int fn, void *data)
 	for (i = fn; i < MAP_SIZE; i += TASKS) {
 		key = value = i;
 		if (do_update)
-			assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
+			assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == 0);
 		else
-			assert(bpf_delete_elem(map_fd, &key) == 0);
+			assert(bpf_map_delete_elem(map_fd, &key) == 0);
 	}
 }
 
@@ -254,19 +254,19 @@ static void test_map_parallel(void)
 	run_parallel(TASKS, do_work, data);
 
 	/* check that key=0 is already there */
-	assert(bpf_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
+	assert(bpf_map_update_elem(map_fd, &key, &value, BPF_NOEXIST) == -1 &&
 	       errno == EEXIST);
 
 	/* check that all elements were inserted */
 	key = -1;
 	for (i = 0; i < MAP_SIZE; i++)
-		assert(bpf_get_next_key(map_fd, &key, &key) == 0);
-	assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+		assert(bpf_map_get_next_key(map_fd, &key, &key) == 0);
+	assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
 
 	/* another check for all elements */
 	for (i = 0; i < MAP_SIZE; i++) {
 		key = MAP_SIZE - i - 1;
-		assert(bpf_lookup_elem(map_fd, &key, &value) == 0 &&
+		assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0 &&
 		       value == key);
 	}
 
@@ -276,7 +276,7 @@ static void test_map_parallel(void)
 
 	/* nothing should be left */
 	key = -1;
-	assert(bpf_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
+	assert(bpf_map_get_next_key(map_fd, &key, &key) == -1 && errno == ENOENT);
 }
 
 int main(void)
diff --git a/samples/bpf/test_verifier.c b/samples/bpf/test_verifier.c
index 563c507..0566fc0 100644
--- a/samples/bpf/test_verifier.c
+++ b/samples/bpf/test_verifier.c
@@ -17,13 +17,17 @@
 #include <stddef.h>
 #include <stdbool.h>
 #include <sys/resource.h>
-#include "libbpf.h"
+#include "utils.h"
+#include <bpf/bpf.h>
 
 #define MAX_INSNS 512
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
 
 #define MAX_FIXUPS 8
 
+#define LOG_BUF_SIZE 65536
+static char bpf_log_buf[LOG_BUF_SIZE];
+
 struct bpf_test {
 	const char *descr;
 	struct bpf_insn	insns[MAX_INSNS];
@@ -1250,9 +1254,10 @@ static int test(void)
 		}
 		printf("#%d %s ", i, tests[i].descr);
 
-		prog_fd = bpf_prog_load(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
-					prog, prog_len * sizeof(struct bpf_insn),
-					"GPL", 0);
+		bpf_log_buf[0] = '\0';
+		prog_fd = bpf_load_program(prog_type ?: BPF_PROG_TYPE_SOCKET_FILTER,
+					   prog, prog_len, "GPL", 0,
+					   bpf_log_buf, sizeof(bpf_log_buf));
 
 		if (unpriv && tests[i].result_unpriv != UNDEF)
 			expected_result = tests[i].result_unpriv;
diff --git a/samples/bpf/trace_output_user.c b/samples/bpf/trace_output_user.c
index 661a7d0..4ef02cb 100644
--- a/samples/bpf/trace_output_user.c
+++ b/samples/bpf/trace_output_user.c
@@ -19,8 +19,7 @@
 #include <sys/mman.h>
 #include <time.h>
 #include <signal.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 static int pmu_fd;
 
@@ -61,7 +60,7 @@ struct perf_event_sample {
 	char data[];
 };
 
-void perf_event_read(print_fn fn)
+static void perf_event_read(print_fn fn)
 {
 	__u64 data_tail = header->data_tail;
 	__u64 data_head = header->data_head;
@@ -150,7 +149,7 @@ static void print_bpf_output(void *data, int size)
 	}
 }
 
-static void test_bpf_perf_event(void)
+static void test_bpf_perf_event(int map_fd)
 {
 	struct perf_event_attr attr = {
 		.sample_type = PERF_SAMPLE_RAW,
@@ -162,7 +161,7 @@ static void test_bpf_perf_event(void)
 	pmu_fd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
 
 	assert(pmu_fd >= 0);
-	assert(bpf_update_elem(map_fd[0], &key, &pmu_fd, BPF_ANY) == 0);
+	assert(bpf_map_update_elem(map_fd, &key, &pmu_fd, BPF_ANY) == 0);
 	ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
 }
 
@@ -170,15 +169,15 @@ int main(int argc, char **argv)
 {
 	char filename[256];
 	FILE *f;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
-	test_bpf_perf_event();
+	test_bpf_perf_event(get_map_fd(obj, 0));
 
 	if (perf_event_mmap(pmu_fd) < 0)
 		return 1;
diff --git a/samples/bpf/tracex1_user.c b/samples/bpf/tracex1_user.c
index 31a4818..0652339 100644
--- a/samples/bpf/tracex1_user.c
+++ b/samples/bpf/tracex1_user.c
@@ -1,20 +1,19 @@
 #include <stdio.h>
 #include <linux/bpf.h>
 #include <unistd.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 int main(int ac, char **argv)
 {
 	FILE *f;
 	char filename[256];
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
 	f = popen("taskset 1 ping -c5 localhost", "r");
 	(void) f;
diff --git a/samples/bpf/tracex2_user.c b/samples/bpf/tracex2_user.c
index cd0241c..86700bb 100644
--- a/samples/bpf/tracex2_user.c
+++ b/samples/bpf/tracex2_user.c
@@ -4,8 +4,9 @@
 #include <signal.h>
 #include <linux/bpf.h>
 #include <string.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include <bpf/libbpf.h>
+#include <bpf/bpf.h>
+#include "utils.h"
 
 #define MAX_INDEX	64
 #define MAX_STARS	38
@@ -44,12 +45,12 @@ static void print_hist_for_pid(int fd, void *task)
 	long max_value = 0;
 	int i, ind;
 
-	while (bpf_get_next_key(fd, &key, &next_key) == 0) {
+	while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
 		if (memcmp(&next_key, task, SIZE)) {
 			key = next_key;
 			continue;
 		}
-		bpf_lookup_elem(fd, &next_key, &value);
+		bpf_map_lookup_elem(fd, &next_key, &value);
 		ind = next_key.index;
 		data[ind] = value;
 		if (value && ind > max_ind)
@@ -76,7 +77,7 @@ static void print_hist(int fd)
 	int task_cnt = 0;
 	int i;
 
-	while (bpf_get_next_key(fd, &key, &next_key) == 0) {
+	while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
 		int found = 0;
 
 		for (i = 0; i < task_cnt; i++)
@@ -97,9 +98,11 @@ static void print_hist(int fd)
 
 }
 
+static int hist_map_fd;
+
 static void int_exit(int sig)
 {
-	print_hist(map_fd[1]);
+	print_hist(hist_map_fd);
 	exit(0);
 }
 
@@ -108,7 +111,8 @@ int main(int ac, char **argv)
 	char filename[256];
 	long key, next_key, value;
 	FILE *f;
-	int i;
+	int i, map_fd;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
@@ -122,15 +126,16 @@ int main(int ac, char **argv)
 	f = popen("dd if=/dev/zero of=/dev/null count=5000000", "r");
 	(void) f;
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
+	map_fd = get_map_fd(obj, 0);
+	hist_map_fd = get_map_fd(obj, 1);
 
 	for (i = 0; i < 5; i++) {
 		key = 0;
-		while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
-			bpf_lookup_elem(map_fd[0], &next_key, &value);
+		while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
+			bpf_map_lookup_elem(map_fd, &next_key, &value);
 			printf("location 0x%lx count %ld\n", next_key, value);
 			key = next_key;
 		}
@@ -138,7 +143,7 @@ int main(int ac, char **argv)
 			printf("\n");
 		sleep(1);
 	}
-	print_hist(map_fd[1]);
+	print_hist(hist_map_fd);
 
 	return 0;
 }
diff --git a/samples/bpf/tracex3_user.c b/samples/bpf/tracex3_user.c
index 0aaa933..4c26a6f 100644
--- a/samples/bpf/tracex3_user.c
+++ b/samples/bpf/tracex3_user.c
@@ -11,8 +11,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
 
@@ -24,7 +23,7 @@ static void clear_stats(int fd)
 	__u64 value = 0;
 
 	for (key = 0; key < SLOTS; key++)
-		bpf_update_elem(fd, &key, &value, BPF_ANY);
+		bpf_map_update_elem(fd, &key, &value, BPF_ANY);
 }
 
 const char *color[] = {
@@ -83,7 +82,7 @@ static void print_hist(int fd)
 
 	for (key = 0; key < SLOTS; key++) {
 		value = 0;
-		bpf_lookup_elem(fd, &key, &value);
+		bpf_map_lookup_elem(fd, &key, &value);
 		cnt[key] = value;
 		total_events += value;
 		if (value > max_cnt)
@@ -105,13 +104,13 @@ int main(int ac, char **argv)
 {
 	char filename[256];
 	int i;
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
 	for (i = 1; i < ac; i++) {
 		if (strcmp(argv[i], "-a") == 0) {
@@ -142,7 +141,7 @@ int main(int ac, char **argv)
 	for (i = 0; ; i++) {
 		if (i % 20 == 0)
 			print_banner();
-		print_hist(map_fd[1]);
+		print_hist(get_map_fd(obj, 1));
 		sleep(2);
 	}
 
diff --git a/samples/bpf/tracex4_user.c b/samples/bpf/tracex4_user.c
index bc4a3bd..273bd33 100644
--- a/samples/bpf/tracex4_user.c
+++ b/samples/bpf/tracex4_user.c
@@ -12,8 +12,7 @@
 #include <string.h>
 #include <time.h>
 #include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 struct pair {
 	long long val;
@@ -37,8 +36,8 @@ static void print_old_objects(int fd)
 	key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */
 
 	key = -1;
-	while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
-		bpf_lookup_elem(map_fd[0], &next_key, &v);
+	while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
+		bpf_map_lookup_elem(fd, &next_key, &v);
 		key = next_key;
 		if (val - v.val < 1000000000ll)
 			/* object was allocated more then 1 sec ago */
@@ -51,17 +50,17 @@ static void print_old_objects(int fd)
 int main(int ac, char **argv)
 {
 	char filename[256];
+	struct bpf_object *obj;
 	int i;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
 	for (i = 0; ; i++) {
-		print_old_objects(map_fd[1]);
+		print_old_objects(get_map_fd(obj, 0));
 		sleep(1);
 	}
 
diff --git a/samples/bpf/tracex5_user.c b/samples/bpf/tracex5_user.c
index a04dd3c..bcbd7fc 100644
--- a/samples/bpf/tracex5_user.c
+++ b/samples/bpf/tracex5_user.c
@@ -4,8 +4,7 @@
 #include <linux/filter.h>
 #include <linux/seccomp.h>
 #include <sys/prctl.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 /* install fake seccomp program to enable seccomp code path inside the kernel,
  * so that our kprobe attached to seccomp_phase1() can be triggered
@@ -27,13 +26,13 @@ int main(int ac, char **argv)
 {
 	FILE *f;
 	char filename[256];
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
 	install_accept_all_seccomp();
 
diff --git a/samples/bpf/tracex6_user.c b/samples/bpf/tracex6_user.c
index 8ea4976..a400e31 100644
--- a/samples/bpf/tracex6_user.c
+++ b/samples/bpf/tracex6_user.c
@@ -8,12 +8,11 @@
 #include <sys/ioctl.h>
 #include <linux/perf_event.h>
 #include <linux/bpf.h>
-#include "libbpf.h"
-#include "bpf_load.h"
+#include "utils.h"
 
 #define SAMPLE_PERIOD  0x7fffffffffffffffULL
 
-static void test_bpf_perf_event(void)
+static void test_bpf_perf_event(int map_fd)
 {
 	int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
 	int *pmu_fd = malloc(nr_cpus * sizeof(int));
@@ -36,7 +35,7 @@ static void test_bpf_perf_event(void)
 			goto exit;
 		}
 
-		bpf_update_elem(map_fd[0], &i, &pmu_fd[i], BPF_ANY);
+		bpf_map_update_elem(map_fd, &i, &pmu_fd[i], BPF_ANY);
 		ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
 	}
 
@@ -50,22 +49,21 @@ static void test_bpf_perf_event(void)
 exit:
 	for (i = 0; i < nr_cpus; i++)
 		close(pmu_fd[i]);
-	close(map_fd[0]);
 	free(pmu_fd);
 }
 
 int main(int argc, char **argv)
 {
 	char filename[256];
+	struct bpf_object *obj;
 
 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 
-	if (load_bpf_file(filename)) {
-		printf("%s", bpf_log_buf);
+	obj = load_bpf_file(filename);
+	if (!obj)
 		return 1;
-	}
 
-	test_bpf_perf_event();
+	test_bpf_perf_event(get_map_fd(obj, 0));
 	read_trace_pipe();
 
 	return 0;
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH 10/10] bpf samples: Remove old BPF helpers
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (8 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 09/10] bpf samples: Uses libbpf in tools/lib to deal with BPF operations Wang Nan
@ 2015-12-17  5:23 ` Wang Nan
  2015-12-17  6:38 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Daniel Wagner
  10 siblings, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  5:23 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Since we have switched to libbpf in tools/lib, old bpf_load.c and
libbpf.c can be removed safely.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Alex Gartrell <agartrell@fb.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Brenden Blanco <bblanco@plumgrid.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kaixu Xia <xiakaixu@huawei.com>
Cc: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Cc: Yang Shi <yang.shi@linaro.org>
---
 samples/bpf/bpf_load.c | 345 -------------------------------------------------
 samples/bpf/bpf_load.h |  27 ----
 samples/bpf/libbpf.c   | 154 ----------------------
 samples/bpf/libbpf.h   | 201 ----------------------------
 4 files changed, 727 deletions(-)
 delete mode 100644 samples/bpf/bpf_load.c
 delete mode 100644 samples/bpf/bpf_load.h
 delete mode 100644 samples/bpf/libbpf.c
 delete mode 100644 samples/bpf/libbpf.h

diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
deleted file mode 100644
index da86a8e..0000000
--- a/samples/bpf/bpf_load.c
+++ /dev/null
@@ -1,345 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <libelf.h>
-#include <gelf.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <linux/bpf.h>
-#include <linux/filter.h>
-#include <linux/perf_event.h>
-#include <sys/syscall.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <poll.h>
-#include <ctype.h>
-#include "libbpf.h"
-#include "bpf_helpers.h"
-#include "bpf_load.h"
-
-#define DEBUGFS "/sys/kernel/debug/tracing/"
-
-static char license[128];
-static int kern_version;
-static bool processed_sec[128];
-int map_fd[MAX_MAPS];
-int prog_fd[MAX_PROGS];
-int event_fd[MAX_PROGS];
-int prog_cnt;
-int prog_array_fd = -1;
-
-static int populate_prog_array(const char *event, int prog_fd)
-{
-	int ind = atoi(event), err;
-
-	err = bpf_update_elem(prog_array_fd, &ind, &prog_fd, BPF_ANY);
-	if (err < 0) {
-		printf("failed to store prog_fd in prog_array\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
-{
-	bool is_socket = strncmp(event, "socket", 6) == 0;
-	bool is_kprobe = strncmp(event, "kprobe/", 7) == 0;
-	bool is_kretprobe = strncmp(event, "kretprobe/", 10) == 0;
-	enum bpf_prog_type prog_type;
-	char buf[256];
-	int fd, efd, err, id;
-	struct perf_event_attr attr = {};
-
-	attr.type = PERF_TYPE_TRACEPOINT;
-	attr.sample_type = PERF_SAMPLE_RAW;
-	attr.sample_period = 1;
-	attr.wakeup_events = 1;
-
-	if (is_socket) {
-		prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
-	} else if (is_kprobe || is_kretprobe) {
-		prog_type = BPF_PROG_TYPE_KPROBE;
-	} else {
-		printf("Unknown event '%s'\n", event);
-		return -1;
-	}
-
-	fd = bpf_prog_load(prog_type, prog, size, license, kern_version);
-	if (fd < 0) {
-		printf("bpf_prog_load() err=%d\n%s", errno, bpf_log_buf);
-		return -1;
-	}
-
-	prog_fd[prog_cnt++] = fd;
-
-	if (is_socket) {
-		event += 6;
-		if (*event != '/')
-			return 0;
-		event++;
-		if (!isdigit(*event)) {
-			printf("invalid prog number\n");
-			return -1;
-		}
-		return populate_prog_array(event, fd);
-	}
-
-	if (is_kprobe || is_kretprobe) {
-		if (is_kprobe)
-			event += 7;
-		else
-			event += 10;
-
-		if (*event == 0) {
-			printf("event name cannot be empty\n");
-			return -1;
-		}
-
-		if (isdigit(*event))
-			return populate_prog_array(event, fd);
-
-		snprintf(buf, sizeof(buf),
-			 "echo '%c:%s %s' >> /sys/kernel/debug/tracing/kprobe_events",
-			 is_kprobe ? 'p' : 'r', event, event);
-		err = system(buf);
-		if (err < 0) {
-			printf("failed to create kprobe '%s' error '%s'\n",
-			       event, strerror(errno));
-			return -1;
-		}
-	}
-
-	strcpy(buf, DEBUGFS);
-	strcat(buf, "events/kprobes/");
-	strcat(buf, event);
-	strcat(buf, "/id");
-
-	efd = open(buf, O_RDONLY, 0);
-	if (efd < 0) {
-		printf("failed to open event %s\n", event);
-		return -1;
-	}
-
-	err = read(efd, buf, sizeof(buf));
-	if (err < 0 || err >= sizeof(buf)) {
-		printf("read from '%s' failed '%s'\n", event, strerror(errno));
-		return -1;
-	}
-
-	close(efd);
-
-	buf[err] = 0;
-	id = atoi(buf);
-	attr.config = id;
-
-	efd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);
-	if (efd < 0) {
-		printf("event %d fd %d err %s\n", id, efd, strerror(errno));
-		return -1;
-	}
-	event_fd[prog_cnt - 1] = efd;
-	ioctl(efd, PERF_EVENT_IOC_ENABLE, 0);
-	ioctl(efd, PERF_EVENT_IOC_SET_BPF, fd);
-
-	return 0;
-}
-
-static int load_maps(struct bpf_map_def *maps, int len)
-{
-	int i;
-
-	for (i = 0; i < len / sizeof(struct bpf_map_def); i++) {
-
-		map_fd[i] = bpf_create_map(maps[i].type,
-					   maps[i].key_size,
-					   maps[i].value_size,
-					   maps[i].max_entries);
-		if (map_fd[i] < 0)
-			return 1;
-
-		if (maps[i].type == BPF_MAP_TYPE_PROG_ARRAY)
-			prog_array_fd = map_fd[i];
-	}
-	return 0;
-}
-
-static int get_sec(Elf *elf, int i, GElf_Ehdr *ehdr, char **shname,
-		   GElf_Shdr *shdr, Elf_Data **data)
-{
-	Elf_Scn *scn;
-
-	scn = elf_getscn(elf, i);
-	if (!scn)
-		return 1;
-
-	if (gelf_getshdr(scn, shdr) != shdr)
-		return 2;
-
-	*shname = elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name);
-	if (!*shname || !shdr->sh_size)
-		return 3;
-
-	*data = elf_getdata(scn, 0);
-	if (!*data || elf_getdata(scn, *data) != NULL)
-		return 4;
-
-	return 0;
-}
-
-static int parse_relo_and_apply(Elf_Data *data, Elf_Data *symbols,
-				GElf_Shdr *shdr, struct bpf_insn *insn)
-{
-	int i, nrels;
-
-	nrels = shdr->sh_size / shdr->sh_entsize;
-
-	for (i = 0; i < nrels; i++) {
-		GElf_Sym sym;
-		GElf_Rel rel;
-		unsigned int insn_idx;
-
-		gelf_getrel(data, i, &rel);
-
-		insn_idx = rel.r_offset / sizeof(struct bpf_insn);
-
-		gelf_getsym(symbols, GELF_R_SYM(rel.r_info), &sym);
-
-		if (insn[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
-			printf("invalid relo for insn[%d].code 0x%x\n",
-			       insn_idx, insn[insn_idx].code);
-			return 1;
-		}
-		insn[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
-		insn[insn_idx].imm = map_fd[sym.st_value / sizeof(struct bpf_map_def)];
-	}
-
-	return 0;
-}
-
-int load_bpf_file(char *path)
-{
-	int fd, i;
-	Elf *elf;
-	GElf_Ehdr ehdr;
-	GElf_Shdr shdr, shdr_prog;
-	Elf_Data *data, *data_prog, *symbols = NULL;
-	char *shname, *shname_prog;
-
-	if (elf_version(EV_CURRENT) == EV_NONE)
-		return 1;
-
-	fd = open(path, O_RDONLY, 0);
-	if (fd < 0)
-		return 1;
-
-	elf = elf_begin(fd, ELF_C_READ, NULL);
-
-	if (!elf)
-		return 1;
-
-	if (gelf_getehdr(elf, &ehdr) != &ehdr)
-		return 1;
-
-	/* clear all kprobes */
-	i = system("echo \"\" > /sys/kernel/debug/tracing/kprobe_events");
-
-	/* scan over all elf sections to get license and map info */
-	for (i = 1; i < ehdr.e_shnum; i++) {
-
-		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
-			continue;
-
-		if (0) /* helpful for llvm debugging */
-			printf("section %d:%s data %p size %zd link %d flags %d\n",
-			       i, shname, data->d_buf, data->d_size,
-			       shdr.sh_link, (int) shdr.sh_flags);
-
-		if (strcmp(shname, "license") == 0) {
-			processed_sec[i] = true;
-			memcpy(license, data->d_buf, data->d_size);
-		} else if (strcmp(shname, "version") == 0) {
-			processed_sec[i] = true;
-			if (data->d_size != sizeof(int)) {
-				printf("invalid size of version section %zd\n",
-				       data->d_size);
-				return 1;
-			}
-			memcpy(&kern_version, data->d_buf, sizeof(int));
-		} else if (strcmp(shname, "maps") == 0) {
-			processed_sec[i] = true;
-			if (load_maps(data->d_buf, data->d_size))
-				return 1;
-		} else if (shdr.sh_type == SHT_SYMTAB) {
-			symbols = data;
-		}
-	}
-
-	/* load programs that need map fixup (relocations) */
-	for (i = 1; i < ehdr.e_shnum; i++) {
-
-		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
-			continue;
-		if (shdr.sh_type == SHT_REL) {
-			struct bpf_insn *insns;
-
-			if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog,
-				    &shdr_prog, &data_prog))
-				continue;
-
-			insns = (struct bpf_insn *) data_prog->d_buf;
-
-			processed_sec[shdr.sh_info] = true;
-			processed_sec[i] = true;
-
-			if (parse_relo_and_apply(data, symbols, &shdr, insns))
-				continue;
-
-			if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
-			    memcmp(shname_prog, "kretprobe/", 10) == 0 ||
-			    memcmp(shname_prog, "socket", 6) == 0)
-				load_and_attach(shname_prog, insns, data_prog->d_size);
-		}
-	}
-
-	/* load programs that don't use maps */
-	for (i = 1; i < ehdr.e_shnum; i++) {
-
-		if (processed_sec[i])
-			continue;
-
-		if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
-			continue;
-
-		if (memcmp(shname, "kprobe/", 7) == 0 ||
-		    memcmp(shname, "kretprobe/", 10) == 0 ||
-		    memcmp(shname, "socket", 6) == 0)
-			load_and_attach(shname, data->d_buf, data->d_size);
-	}
-
-	close(fd);
-	return 0;
-}
-
-void read_trace_pipe(void)
-{
-	int trace_fd;
-
-	trace_fd = open(DEBUGFS "trace_pipe", O_RDONLY, 0);
-	if (trace_fd < 0)
-		return;
-
-	while (1) {
-		static char buf[4096];
-		ssize_t sz;
-
-		sz = read(trace_fd, buf, sizeof(buf));
-		if (sz > 0) {
-			buf[sz] = 0;
-			puts(buf);
-		}
-	}
-}
diff --git a/samples/bpf/bpf_load.h b/samples/bpf/bpf_load.h
deleted file mode 100644
index cbd7c2b..0000000
--- a/samples/bpf/bpf_load.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __BPF_LOAD_H
-#define __BPF_LOAD_H
-
-#define MAX_MAPS 32
-#define MAX_PROGS 32
-
-extern int map_fd[MAX_MAPS];
-extern int prog_fd[MAX_PROGS];
-extern int event_fd[MAX_PROGS];
-
-/* parses elf file compiled by llvm .c->.o
- * . parses 'maps' section and creates maps via BPF syscall
- * . parses 'license' section and passes it to syscall
- * . parses elf relocations for BPF maps and adjusts BPF_LD_IMM64 insns by
- *   storing map_fd into insn->imm and marking such insns as BPF_PSEUDO_MAP_FD
- * . loads eBPF programs via BPF syscall
- *
- * One ELF file can contain multiple BPF programs which will be loaded
- * and their FDs stored stored in prog_fd array
- *
- * returns zero on success
- */
-int load_bpf_file(char *path);
-
-void read_trace_pipe(void);
-
-#endif
diff --git a/samples/bpf/libbpf.c b/samples/bpf/libbpf.c
deleted file mode 100644
index 65a8d48..0000000
--- a/samples/bpf/libbpf.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* eBPF mini library */
-#include <stdlib.h>
-#include <stdio.h>
-#include <linux/unistd.h>
-#include <unistd.h>
-#include <string.h>
-#include <linux/netlink.h>
-#include <linux/bpf.h>
-#include <errno.h>
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <linux/if_packet.h>
-#include <arpa/inet.h>
-#include "libbpf.h"
-
-static __u64 ptr_to_u64(void *ptr)
-{
-	return (__u64) (unsigned long) ptr;
-}
-
-int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
-		   int max_entries)
-{
-	union bpf_attr attr = {
-		.map_type = map_type,
-		.key_size = key_size,
-		.value_size = value_size,
-		.max_entries = max_entries
-	};
-
-	return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
-}
-
-int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
-{
-	union bpf_attr attr = {
-		.map_fd = fd,
-		.key = ptr_to_u64(key),
-		.value = ptr_to_u64(value),
-		.flags = flags,
-	};
-
-	return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
-}
-
-int bpf_lookup_elem(int fd, void *key, void *value)
-{
-	union bpf_attr attr = {
-		.map_fd = fd,
-		.key = ptr_to_u64(key),
-		.value = ptr_to_u64(value),
-	};
-
-	return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
-}
-
-int bpf_delete_elem(int fd, void *key)
-{
-	union bpf_attr attr = {
-		.map_fd = fd,
-		.key = ptr_to_u64(key),
-	};
-
-	return syscall(__NR_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
-}
-
-int bpf_get_next_key(int fd, void *key, void *next_key)
-{
-	union bpf_attr attr = {
-		.map_fd = fd,
-		.key = ptr_to_u64(key),
-		.next_key = ptr_to_u64(next_key),
-	};
-
-	return syscall(__NR_bpf, BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
-}
-
-#define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u))
-
-char bpf_log_buf[LOG_BUF_SIZE];
-
-int bpf_prog_load(enum bpf_prog_type prog_type,
-		  const struct bpf_insn *insns, int prog_len,
-		  const char *license, int kern_version)
-{
-	union bpf_attr attr = {
-		.prog_type = prog_type,
-		.insns = ptr_to_u64((void *) insns),
-		.insn_cnt = prog_len / sizeof(struct bpf_insn),
-		.license = ptr_to_u64((void *) license),
-		.log_buf = ptr_to_u64(bpf_log_buf),
-		.log_size = LOG_BUF_SIZE,
-		.log_level = 1,
-	};
-
-	/* assign one field outside of struct init to make sure any
-	 * padding is zero initialized
-	 */
-	attr.kern_version = kern_version;
-
-	bpf_log_buf[0] = 0;
-
-	return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
-}
-
-int bpf_obj_pin(int fd, const char *pathname)
-{
-	union bpf_attr attr = {
-		.pathname	= ptr_to_u64((void *)pathname),
-		.bpf_fd		= fd,
-	};
-
-	return syscall(__NR_bpf, BPF_OBJ_PIN, &attr, sizeof(attr));
-}
-
-int bpf_obj_get(const char *pathname)
-{
-	union bpf_attr attr = {
-		.pathname	= ptr_to_u64((void *)pathname),
-	};
-
-	return syscall(__NR_bpf, BPF_OBJ_GET, &attr, sizeof(attr));
-}
-
-int open_raw_sock(const char *name)
-{
-	struct sockaddr_ll sll;
-	int sock;
-
-	sock = socket(PF_PACKET, SOCK_RAW | SOCK_NONBLOCK | SOCK_CLOEXEC, htons(ETH_P_ALL));
-	if (sock < 0) {
-		printf("cannot create raw socket\n");
-		return -1;
-	}
-
-	memset(&sll, 0, sizeof(sll));
-	sll.sll_family = AF_PACKET;
-	sll.sll_ifindex = if_nametoindex(name);
-	sll.sll_protocol = htons(ETH_P_ALL);
-	if (bind(sock, (struct sockaddr *)&sll, sizeof(sll)) < 0) {
-		printf("bind to %s: %s\n", name, strerror(errno));
-		close(sock);
-		return -1;
-	}
-
-	return sock;
-}
-
-int perf_event_open(struct perf_event_attr *attr, int pid, int cpu,
-		    int group_fd, unsigned long flags)
-{
-	return syscall(__NR_perf_event_open, attr, pid, cpu,
-		       group_fd, flags);
-}
diff --git a/samples/bpf/libbpf.h b/samples/bpf/libbpf.h
deleted file mode 100644
index 014aacf..0000000
--- a/samples/bpf/libbpf.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/* eBPF mini library */
-#ifndef __LIBBPF_H
-#define __LIBBPF_H
-
-struct bpf_insn;
-
-int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
-		   int max_entries);
-int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags);
-int bpf_lookup_elem(int fd, void *key, void *value);
-int bpf_delete_elem(int fd, void *key);
-int bpf_get_next_key(int fd, void *key, void *next_key);
-
-int bpf_prog_load(enum bpf_prog_type prog_type,
-		  const struct bpf_insn *insns, int insn_len,
-		  const char *license, int kern_version);
-
-int bpf_obj_pin(int fd, const char *pathname);
-int bpf_obj_get(const char *pathname);
-
-#define LOG_BUF_SIZE 65536
-extern char bpf_log_buf[LOG_BUF_SIZE];
-
-/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
-
-#define BPF_ALU64_REG(OP, DST, SRC)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = 0,					\
-		.imm   = 0 })
-
-#define BPF_ALU32_REG(OP, DST, SRC)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU | BPF_OP(OP) | BPF_X,		\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = 0,					\
-		.imm   = 0 })
-
-/* ALU ops on immediates, bpf_add|sub|...: dst_reg += imm32 */
-
-#define BPF_ALU64_IMM(OP, DST, IMM)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
-		.dst_reg = DST,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = IMM })
-
-#define BPF_ALU32_IMM(OP, DST, IMM)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU | BPF_OP(OP) | BPF_K,		\
-		.dst_reg = DST,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = IMM })
-
-/* Short form of mov, dst_reg = src_reg */
-
-#define BPF_MOV64_REG(DST, SRC)					\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = 0,					\
-		.imm   = 0 })
-
-#define BPF_MOV32_REG(DST, SRC)					\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU | BPF_MOV | BPF_X,		\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = 0,					\
-		.imm   = 0 })
-
-/* Short form of mov, dst_reg = imm32 */
-
-#define BPF_MOV64_IMM(DST, IMM)					\
-	((struct bpf_insn) {					\
-		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
-		.dst_reg = DST,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = IMM })
-
-/* BPF_LD_IMM64 macro encodes single 'load 64-bit immediate' insn */
-#define BPF_LD_IMM64(DST, IMM)					\
-	BPF_LD_IMM64_RAW(DST, 0, IMM)
-
-#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_LD | BPF_DW | BPF_IMM,		\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = 0,					\
-		.imm   = (__u32) (IMM) }),			\
-	((struct bpf_insn) {					\
-		.code  = 0, /* zero is reserved opcode */	\
-		.dst_reg = 0,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = ((__u64) (IMM)) >> 32 })
-
-#ifndef BPF_PSEUDO_MAP_FD
-# define BPF_PSEUDO_MAP_FD	1
-#endif
-
-/* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
-#define BPF_LD_MAP_FD(DST, MAP_FD)				\
-	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
-
-
-/* Direct packet access, R0 = *(uint *) (skb->data + imm32) */
-
-#define BPF_LD_ABS(SIZE, IMM)					\
-	((struct bpf_insn) {					\
-		.code  = BPF_LD | BPF_SIZE(SIZE) | BPF_ABS,	\
-		.dst_reg = 0,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = IMM })
-
-/* Memory load, dst_reg = *(uint *) (src_reg + off16) */
-
-#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
-	((struct bpf_insn) {					\
-		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = OFF,					\
-		.imm   = 0 })
-
-/* Memory store, *(uint *) (dst_reg + off16) = src_reg */
-
-#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
-	((struct bpf_insn) {					\
-		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = OFF,					\
-		.imm   = 0 })
-
-/* Memory store, *(uint *) (dst_reg + off16) = imm32 */
-
-#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
-		.dst_reg = DST,					\
-		.src_reg = 0,					\
-		.off   = OFF,					\
-		.imm   = IMM })
-
-/* Conditional jumps against registers, if (dst_reg 'op' src_reg) goto pc + off16 */
-
-#define BPF_JMP_REG(OP, DST, SRC, OFF)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_JMP | BPF_OP(OP) | BPF_X,		\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = OFF,					\
-		.imm   = 0 })
-
-/* Conditional jumps against immediates, if (dst_reg 'op' imm32) goto pc + off16 */
-
-#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
-	((struct bpf_insn) {					\
-		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
-		.dst_reg = DST,					\
-		.src_reg = 0,					\
-		.off   = OFF,					\
-		.imm   = IMM })
-
-/* Raw code statement block */
-
-#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
-	((struct bpf_insn) {					\
-		.code  = CODE,					\
-		.dst_reg = DST,					\
-		.src_reg = SRC,					\
-		.off   = OFF,					\
-		.imm   = IMM })
-
-/* Program exit */
-
-#define BPF_EXIT_INSN()						\
-	((struct bpf_insn) {					\
-		.code  = BPF_JMP | BPF_EXIT,			\
-		.dst_reg = 0,					\
-		.src_reg = 0,					\
-		.off   = 0,					\
-		.imm   = 0 })
-
-/* create RAW socket and bind to interface 'name' */
-int open_raw_sock(const char *name);
-
-struct perf_event_attr;
-int perf_event_open(struct perf_event_attr *attr, int pid, int cpu,
-		    int group_fd, unsigned long flags);
-#endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 06/10] bpf tools: Support new map operations
  2015-12-17  5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
@ 2015-12-17  6:06   ` Wangnan (F)
  2015-12-17  6:09   ` [PATCH v2 " Wang Nan
  1 sibling, 0 replies; 35+ messages in thread
From: Wangnan (F) @ 2015-12-17  6:06 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama


[SNIP]
> +int bpf_map_lookup_elem(int fd, void *key, void *value)
> +{
> +	union bpf_attr attr = {
> +		.map_fd = fd,
> +		.key = ptr_to_u64(key),
> +		.value = ptr_to_u64(value),
> +	};
Tailing whitespace here. Sorry...



^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH v2 06/10] bpf tools: Support new map operations
  2015-12-17  5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
  2015-12-17  6:06   ` Wangnan (F)
@ 2015-12-17  6:09   ` Wang Nan
  1 sibling, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-17  6:09 UTC (permalink / raw)
  To: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama, Wang Nan

Add bpf_map_lookup_elem(), bpf_map_delete_elem() and bpf_map_get_next_key()
to libbpf so it can issue all BPF map operations.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
---

v1 -> v2: Remove tailing whitespaces.

---
 tools/lib/bpf/bpf.c | 32 ++++++++++++++++++++++++++++++++
 tools/lib/bpf/bpf.h |  4 ++++
 2 files changed, 36 insertions(+)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index e0dccea..b8e7aaa 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -97,3 +97,35 @@ int bpf_map_update_elem(int fd, void *key, void *value,
 
 	return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
 }
+
+int bpf_map_lookup_elem(int fd, void *key, void *value)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+		.value = ptr_to_u64(value),
+	};
+
+	return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
+}
+
+int bpf_map_delete_elem(int fd, void *key)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+	};
+
+	return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
+}
+
+int bpf_map_get_next_key(int fd, void *key, void *next_key)
+{
+	union bpf_attr attr = {
+		.map_fd = fd,
+		.key = ptr_to_u64(key),
+		.next_key = ptr_to_u64(next_key),
+	};
+
+	return sys_bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 01a421a..3d22048 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -23,4 +23,8 @@ int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
 
 int bpf_map_update_elem(int fd, void *key, void *value,
 			__u64 flags);
+
+int bpf_map_lookup_elem(int fd, void *key, void *value);
+int bpf_map_delete_elem(int fd, void *key);
+int bpf_map_get_next_key(int fd, void *key, void *next_key);
 #endif
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
                   ` (9 preceding siblings ...)
  2015-12-17  5:23 ` [PATCH 10/10] bpf samples: Remove old BPF helpers Wang Nan
@ 2015-12-17  6:38 ` Daniel Wagner
  2015-12-17  6:51   ` Wangnan (F)
  10 siblings, 1 reply; 35+ messages in thread
From: Daniel Wagner @ 2015-12-17  6:38 UTC (permalink / raw)
  To: Wang Nan, ast, agartrell, acme, bblanco, daniel, davem, mingo,
	jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

Hi,

On 12/17/2015 06:23 AM, Wang Nan wrote:
> Since we already have libbpf in tools/lib, we don't need to maintain
> another bpf loader and operations library in samples/bpf.
> 
> In patchset:
> 
>  Patch 1/10 - 7/10 improves libbpf, add missing features to support
>  samples,
> 
>  Patch 8/10 adds utils.[ch], which creates similar API like old
>  bpf_load.c and libbpf.c.
> 
>  Patch 9/10 replace all sampels to use API provides by utils.[ch] and
>  libbpf.
> 
>  Patch 10/10 removes unneeded files.

Which tree did you use for your patches? I tried to apply them against
mainline and net-next which didn't really work out.

cheers,
daniel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17  6:38 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Daniel Wagner
@ 2015-12-17  6:51   ` Wangnan (F)
  2015-12-17  7:03     ` Daniel Wagner
  0 siblings, 1 reply; 35+ messages in thread
From: Wangnan (F) @ 2015-12-17  6:51 UTC (permalink / raw)
  To: Daniel Wagner, ast, agartrell, acme, bblanco, daniel, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama



On 2015/12/17 14:38, Daniel Wagner wrote:
> Hi,
>
> On 12/17/2015 06:23 AM, Wang Nan wrote:
>> Since we already have libbpf in tools/lib, we don't need to maintain
>> another bpf loader and operations library in samples/bpf.
>>
>> In patchset:
>>
>>   Patch 1/10 - 7/10 improves libbpf, add missing features to support
>>   samples,
>>
>>   Patch 8/10 adds utils.[ch], which creates similar API like old
>>   bpf_load.c and libbpf.c.
>>
>>   Patch 9/10 replace all sampels to use API provides by utils.[ch] and
>>   libbpf.
>>
>>   Patch 10/10 removes unneeded files.
> Which tree did you use for your patches? I tried to apply them against
> mainline and net-next which didn't really work out.

These patches based on Arnaldo's 'perf/core' because of those libbpf
changes.

Which tree is the right one for this? net-next?

Thank you.

> cheers,
> daniel



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17  6:51   ` Wangnan (F)
@ 2015-12-17  7:03     ` Daniel Wagner
  2015-12-17  8:29       ` Daniel Wagner
  0 siblings, 1 reply; 35+ messages in thread
From: Daniel Wagner @ 2015-12-17  7:03 UTC (permalink / raw)
  To: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

On 12/17/2015 07:51 AM, Wangnan (F) wrote:
> On 2015/12/17 14:38, Daniel Wagner wrote:
>> On 12/17/2015 06:23 AM, Wang Nan wrote:
>>> Since we already have libbpf in tools/lib, we don't need to maintain
>>> another bpf loader and operations library in samples/bpf.
>>>
>>> In patchset:
>>>
>>>   Patch 1/10 - 7/10 improves libbpf, add missing features to support
>>>   samples,
>>>
>>>   Patch 8/10 adds utils.[ch], which creates similar API like old
>>>   bpf_load.c and libbpf.c.
>>>
>>>   Patch 9/10 replace all sampels to use API provides by utils.[ch] and
>>>   libbpf.
>>>
>>>   Patch 10/10 removes unneeded files.
>> Which tree did you use for your patches? I tried to apply them against
>> mainline and net-next which didn't really work out.
> 
> These patches based on Arnaldo's 'perf/core' because of those libbpf
> changes.

Okay, I'll try with this one.

> Which tree is the right one for this? net-next?

The patches I was involved were routed via net-next but I don't know if
that is the right tree for this patch set.

cheers,
daniel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17  7:03     ` Daniel Wagner
@ 2015-12-17  8:29       ` Daniel Wagner
  2015-12-17 10:09         ` Wangnan (F)
  0 siblings, 1 reply; 35+ messages in thread
From: Daniel Wagner @ 2015-12-17  8:29 UTC (permalink / raw)
  To: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

On 12/17/2015 08:03 AM, Daniel Wagner wrote:
> On 12/17/2015 07:51 AM, Wangnan (F) wrote:
>> On 2015/12/17 14:38, Daniel Wagner wrote:
>>> On 12/17/2015 06:23 AM, Wang Nan wrote:
>>>> Since we already have libbpf in tools/lib, we don't need to maintain
>>>> another bpf loader and operations library in samples/bpf.
>>>>
>>>> In patchset:
>>>>
>>>>   Patch 1/10 - 7/10 improves libbpf, add missing features to support
>>>>   samples,
>>>>
>>>>   Patch 8/10 adds utils.[ch], which creates similar API like old
>>>>   bpf_load.c and libbpf.c.
>>>>
>>>>   Patch 9/10 replace all sampels to use API provides by utils.[ch] and
>>>>   libbpf.
>>>>
>>>>   Patch 10/10 removes unneeded files.
>>> Which tree did you use for your patches? I tried to apply them against
>>> mainline and net-next which didn't really work out.
>>
>> These patches based on Arnaldo's 'perf/core' because of those libbpf
>> changes.
> 
> Okay, I'll try with this one.

I applied those patches on top of

5c560cfcf1c0 ("tools subcmd: Rename subcmd header include guards")

Patch number 2 didn't apply cleanly. After fixing this manually 
I was able to continue to the build step:

$ make samples/bpf/
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
No libelf found
Makefile:203: recipe for target 'elfdep' failed
make[2]: *** [elfdep] Error 255
samples/bpf/Makefile:10: recipe for target 'samples/bpf/libbpf/libbpf.a' failed
make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
Makefile:1550: recipe for target 'samples/bpf/' failed
make: *** [samples/bpf/] Error 2


Executing the above command line by myself in order 
to figure out what's going on ended in this mess:


$ make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
make: Entering directory '/home/wagi/src/linux/tools/lib/bpf'

Auto-detecting system features:
...                        libelf: [ on  ]
...                           bpf: [ on  ]

[...]

samples/bpf/fds_example.c: In function ‘bpf_do_map’:
samples/bpf/fds_example.c:78:9: warning: implicit declaration of function ‘bpf_pin_object’ [-Wimplicit-function-declaration]
   ret = bpf_pin_object(fd, file);
         ^
samples/bpf/fds_example.c:82:8: warning: implicit declaration of function ‘bpf_get_pinned_object’ [-Wimplicit-function-declaration]
   fd = bpf_get_pinned_object(file);
        ^
  gcc -Lsamples/bpf/libbpf -o samples/bpf/fds_example samples/bpf/utils.o samples/bpf/fds_example.o -lelf -lbpf 
samples/bpf/fds_example.o: In function `main':
fds_example.c:(.text.startup+0x20e): undefined reference to `bpf_pin_object'
fds_example.c:(.text.startup+0x2b0): undefined reference to `bpf_pin_object'
fds_example.c:(.text.startup+0x2f3): undefined reference to `bpf_get_pinned_object'
fds_example.c:(.text.startup+0x344): undefined reference to `bpf_get_pinned_object'
collect2: error: ld returned 1 exit status
scripts/Makefile.host:100: recipe for target 'samples/bpf/fds_example' failed
make[1]: *** [samples/bpf/fds_example] Error 1
Makefile:1550: recipe for target 'samples/bpf/' failed
make: *** [samples/bpf/] Error 2
[wagi@handman linux (bpf-test)]$ make samples/bpf/
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  HOSTLD  samples/bpf/fds_example
samples/bpf/fds_example.o: In function `main':
fds_example.c:(.text.startup+0x20e): undefined reference to `bpf_pin_object'
fds_example.c:(.text.startup+0x2b0): undefined reference to `bpf_pin_object'
fds_example.c:(.text.startup+0x2f3): undefined reference to `bpf_get_pinned_object'
fds_example.c:(.text.startup+0x344): undefined reference to `bpf_get_pinned_object'
collect2: error: ld returned 1 exit status


What is the canonical why to build the samples? I must doing something
really stupid I guess.


cheers,
daniel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17  8:29       ` Daniel Wagner
@ 2015-12-17 10:09         ` Wangnan (F)
  2015-12-17 13:46           ` Daniel Wagner
  0 siblings, 1 reply; 35+ messages in thread
From: Wangnan (F) @ 2015-12-17 10:09 UTC (permalink / raw)
  To: Daniel Wagner, ast, agartrell, acme, bblanco, daniel, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama



On 2015/12/17 16:29, Daniel Wagner wrote:
> On 12/17/2015 08:03 AM, Daniel Wagner wrote:
>> On 12/17/2015 07:51 AM, Wangnan (F) wrote:
>>> On 2015/12/17 14:38, Daniel Wagner wrote:
>>>> On 12/17/2015 06:23 AM, Wang Nan wrote:
>>>>> Since we already have libbpf in tools/lib, we don't need to maintain
>>>>> another bpf loader and operations library in samples/bpf.
>>>>>
>>>>> In patchset:
>>>>>
>>>>>    Patch 1/10 - 7/10 improves libbpf, add missing features to support
>>>>>    samples,
>>>>>
>>>>>    Patch 8/10 adds utils.[ch], which creates similar API like old
>>>>>    bpf_load.c and libbpf.c.
>>>>>
>>>>>    Patch 9/10 replace all sampels to use API provides by utils.[ch] and
>>>>>    libbpf.
>>>>>
>>>>>    Patch 10/10 removes unneeded files.
>>>> Which tree did you use for your patches? I tried to apply them against
>>>> mainline and net-next which didn't really work out.
>>> These patches based on Arnaldo's 'perf/core' because of those libbpf
>>> changes.
>> Okay, I'll try with this one.
> I applied those patches on top of
>
> 5c560cfcf1c0 ("tools subcmd: Rename subcmd header include guards")
>
> Patch number 2 didn't apply cleanly.

Because I have another patch in my local tree which also modifis bpf 
Makefile:

http://lkml.kernel.org/g/1450316632-152513-1-git-send-email-wangnan0@huawei.com

sorry.

> After fixing this manually
> I was able to continue to the build step:
>
> $ make samples/bpf/
>    CHK     include/config/kernel.release
>    CHK     include/generated/uapi/linux/version.h
>    CHK     include/generated/utsrelease.h
>    CHK     include/generated/bounds.h
>    CHK     include/generated/timeconst.h
>    CHK     include/generated/asm-offsets.h
>    CALL    scripts/checksyscalls.sh
> make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
> No libelf found
> Makefile:203: recipe for target 'elfdep' failed
> make[2]: *** [elfdep] Error 255
> samples/bpf/Makefile:10: recipe for target 'samples/bpf/libbpf/libbpf.a' failed
> make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
> Makefile:1550: recipe for target 'samples/bpf/' failed
> make: *** [samples/bpf/] Error 2

When you see this, could you please have a look at:

/home/wagi/src/linux/samples/bpf/libbpf/feature/test-*.make.output

?

This error means it can't find libelf on your platform, but it is not true obviously.


>
> Executing the above command line by myself in order
> to figure out what's going on ended in this mess:
>
>
> $ make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
> make: Entering directory '/home/wagi/src/linux/tools/lib/bpf'
>
> Auto-detecting system features:
> ...                        libelf: [ on  ]
> ...                           bpf: [ on  ]
>
> [...]
>
> samples/bpf/fds_example.c: In function ‘bpf_do_map’:
> samples/bpf/fds_example.c:78:9: warning: implicit declaration of function ‘bpf_pin_object’ [-Wimplicit-function-declaration]
>     ret = bpf_pin_object(fd, file);
>           ^
> samples/bpf/fds_example.c:82:8: warning: implicit declaration of function ‘bpf_get_pinned_object’ [-Wimplicit-function-declaration]
>     fd = bpf_get_pinned_object(file);
>          ^
>    gcc -Lsamples/bpf/libbpf -o samples/bpf/fds_example samples/bpf/utils.o samples/bpf/fds_example.o -lelf -lbpf
> samples/bpf/fds_example.o: In function `main':
> fds_example.c:(.text.startup+0x20e): undefined reference to `bpf_pin_object'
> fds_example.c:(.text.startup+0x2b0): undefined reference to `bpf_pin_object'
> fds_example.c:(.text.startup+0x2f3): undefined reference to `bpf_get_pinned_object'
> fds_example.c:(.text.startup+0x344): undefined reference to `bpf_get_pinned_object'
> collect2: error: ld returned 1 exit status
> scripts/Makefile.host:100: recipe for target 'samples/bpf/fds_example' failed
> make[1]: *** [samples/bpf/fds_example] Error 1
> Makefile:1550: recipe for target 'samples/bpf/' failed
> make: *** [samples/bpf/] Error 2
> [wagi@handman linux (bpf-test)]$ make samples/bpf/
>    CHK     include/config/kernel.release
>    CHK     include/generated/uapi/linux/version.h
>    CHK     include/generated/utsrelease.h
>    CHK     include/generated/bounds.h
>    CHK     include/generated/timeconst.h
>    CHK     include/generated/asm-offsets.h
>    CALL    scripts/checksyscalls.sh
>    HOSTLD  samples/bpf/fds_example
> samples/bpf/fds_example.o: In function `main':
> fds_example.c:(.text.startup+0x20e): undefined reference to `bpf_pin_object'
> fds_example.c:(.text.startup+0x2b0): undefined reference to `bpf_pin_object'
> fds_example.c:(.text.startup+0x2f3): undefined reference to `bpf_get_pinned_object'
> fds_example.c:(.text.startup+0x344): undefined reference to `bpf_get_pinned_object'
> collect2: error: ld returned 1 exit status
>

Could you please check whether this patch:

  bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET

is applied properly?

Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17 10:09         ` Wangnan (F)
@ 2015-12-17 13:46           ` Daniel Wagner
  2015-12-18  3:04             ` Wangnan (F)
  0 siblings, 1 reply; 35+ messages in thread
From: Daniel Wagner @ 2015-12-17 13:46 UTC (permalink / raw)
  To: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

On 12/17/2015 11:09 AM, Wangnan (F) wrote:
> On 2015/12/17 16:29, Daniel Wagner wrote:
>> On 12/17/2015 08:03 AM, Daniel Wagner wrote:
>> Patch number 2 didn't apply cleanly.
> 
> Because I have another patch in my local tree which also modifis bpf
> Makefile:
> 
> http://lkml.kernel.org/g/1450316632-152513-1-git-send-email-wangnan0@huawei.com
> 
> sorry.

Ah, that explains it this problem.

>> After fixing this manually
>> I was able to continue to the build step:
>>
>> $ make samples/bpf/
>>    CHK     include/config/kernel.release
>>    CHK     include/generated/uapi/linux/version.h
>>    CHK     include/generated/utsrelease.h
>>    CHK     include/generated/bounds.h
>>    CHK     include/generated/timeconst.h
>>    CHK     include/generated/asm-offsets.h
>>    CALL    scripts/checksyscalls.sh
>> make -C /home/wagi/src/linux/tools/lib/bpf
>> O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1
>> /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
>> No libelf found
>> Makefile:203: recipe for target 'elfdep' failed
>> make[2]: *** [elfdep] Error 255
>> samples/bpf/Makefile:10: recipe for target
>> 'samples/bpf/libbpf/libbpf.a' failed
>> make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
>> Makefile:1550: recipe for target 'samples/bpf/' failed
>> make: *** [samples/bpf/] Error 2
> 
> When you see this, could you please have a look at:
> 
> /home/wagi/src/linux/samples/bpf/libbpf/feature/test-*.make.output
> 
> ?

test-libpython.c:1:20: fatal error: Python.h: No such file or directory

$ find /usr/include -name Python.h
/usr/include/python3.4m/Python.h
/usr/include/python2.7/Python.h

Adding a symlink to /usr/include/Python.h to
/usr/include/python2.7/Python.h didn't help.

> This error means it can't find libelf on your platform, but it is not
> true obviously.

Yeah look like. Funny thing though is if I build libelf directly

$  make -C tools/lib/bpf/
make: Entering directory '/home/wagi/src/linux/tools/lib/bpf'

Auto-detecting system features:
...                        libelf: [ on  ]
...                           bpf: [ on  ]

  CC       fixdep.o
  LD       fixdep-in.o
  LINK     fixdep
  CC       libbpf.o
  CC       bpf.o
  LD       libbpf-in.o
  LINK     libbpf.a
  LINK     libbpf.so
make: Leaving directory '/home/wagi/src/linux/tools/lib/bpf'

all is fine.

>> fds_example.c:(.text.startup+0x20e): undefined reference to
>> `bpf_pin_object'
>> fds_example.c:(.text.startup+0x2b0): undefined reference to
>> `bpf_pin_object'
>> fds_example.c:(.text.startup+0x2f3): undefined reference to
>> `bpf_get_pinned_object'
>> fds_example.c:(.text.startup+0x344): undefined reference to
>> `bpf_get_pinned_object'
>> collect2: error: ld returned 1 exit status
>>
> 
> Could you please check whether this patch:
> 
>  bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET
> 
> is applied properly?

No it wasn't. Sorry about that one. I didn't pay enough attention when
applying them. The v2 of 6 did upset my workflow.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-17  5:23 ` [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF Wang Nan
@ 2015-12-17 23:11   ` Alexei Starovoitov
  2015-12-18  1:47     ` Wangnan (F)
  0 siblings, 1 reply; 35+ messages in thread
From: Alexei Starovoitov @ 2015-12-17 23:11 UTC (permalink / raw)
  To: Wang Nan
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama

On Thu, Dec 17, 2015 at 05:23:12AM +0000, Wang Nan wrote:
> We are going to uses libbpf to replace old libbpf.[ch] and
> bpf_load.[ch]. This is the first patch of this work. In this patch,
> several macros and helpers in libbpf.[ch] and bpf_load.[ch] are
> merged into utils.[ch]. utils.[ch] utilizes libbpf in tools/lib to
> deal with BPF related things. They would be compiled after Makefile
> changes.
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
...
> +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
> +
> +static inline void * __must_check ERR_PTR(long error_)
> +{
> +	return (void *) error_;
> +}
> +
> +static inline long __must_check PTR_ERR(__force const void *ptr)
> +{
> +	return (long) ptr;
> +}
> +
> +static inline bool __must_check IS_ERR(__force const void *ptr)
> +{
> +	return IS_ERR_VALUE((unsigned long)ptr);
> +}

why copy paste this? I don't see the code that uses that.

> +	bpf_object__for_each_program(prog, obj) {
> +		const char *event = bpf_program__title(prog, false);
> +		int fd, err;
> +
> +		LIBBPF_PTR_ASSERT(event, goto errout);
> +		__LIBBPF_ASSERT(fd = bpf_program__nth_fd(prog, 0),
> +				>= 0,
> +				goto errout);
> +
> +		if (strncmp(event, "kprobe/", 7) == 0)
> +			err = create_kprobes(fd, event + 7, true);
> +		else if (strncmp(event, "kretprobe/", 10) == 0)
> +			err = create_kprobes(fd, event + 10, false);

I have a feeling that all bpf+socket, tcbpf1_kernc and trace_output_*.c
are broken, since I don't see a code that attaches programs to sockets
and to perf_event.
How did you test it?

> diff --git a/samples/bpf/utils.h b/samples/bpf/utils.h
> new file mode 100644
> index 0000000..5962a68
> --- /dev/null
> +++ b/samples/bpf/utils.h
> @@ -0,0 +1,217 @@
> +#ifndef __SAMPELS_UTILS_H
> +#define __SAMPELS_UTILS_H
> +
> +#include <bpf/libbpf.h>
> +#include <bpf/bpf.h>
> +
> +/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
> +
> +#define BPF_ALU64_REG(OP, DST, SRC)				\
> +	((struct bpf_insn) {					\
> +		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
> +		.dst_reg = DST,					\
> +		.src_reg = SRC,					\
> +		.off   = 0,					\
> +		.imm   = 0 })

this probably belongs in tools/lib/bpf/bpf.h instead of samples.

The whole set depends on changes in perf/core tree, but
in net-next we have extra commit 30b50aa612018, so I don't see an easy way
to route this patch without creating across-tree merge conflicts during
merge window.
I'd suggest to apply all required work to tools/lib/bpf/ into perf/core
and leave samples/bpf/ after merge window.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-17 23:11   ` Alexei Starovoitov
@ 2015-12-18  1:47     ` Wangnan (F)
  2015-12-18  6:19       ` Alexei Starovoitov
  0 siblings, 1 reply; 35+ messages in thread
From: Wangnan (F) @ 2015-12-18  1:47 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama



On 2015/12/18 7:11, Alexei Starovoitov wrote:
> On Thu, Dec 17, 2015 at 05:23:12AM +0000, Wang Nan wrote:
>> We are going to uses libbpf to replace old libbpf.[ch] and
>> bpf_load.[ch]. This is the first patch of this work. In this patch,
>> several macros and helpers in libbpf.[ch] and bpf_load.[ch] are
>> merged into utils.[ch]. utils.[ch] utilizes libbpf in tools/lib to
>> deal with BPF related things. They would be compiled after Makefile
>> changes.
>>
>> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> ...
>> +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
>> +
>> +static inline void * __must_check ERR_PTR(long error_)
>> +{
>> +	return (void *) error_;
>> +}
>> +
>> +static inline long __must_check PTR_ERR(__force const void *ptr)
>> +{
>> +	return (long) ptr;
>> +}
>> +
>> +static inline bool __must_check IS_ERR(__force const void *ptr)
>> +{
>> +	return IS_ERR_VALUE((unsigned long)ptr);
>> +}
> why copy paste this? I don't see the code that uses that.

This is a limitation in tools/lib/bpf/libbpf.h, which has a #include 
<linux/err.h>
in its header.

libbpf.h requires this include because its API uses ERR_PTR() to encode 
error code.
For example, when calling bpf_object__open(), caller should use IS_ERR() 
to check its
return value instead of compare with NULL, and use PTR_ERR() to retrive 
error number.

However, linux/err.h is not a part of uapi. To make libbpf work, one has 
to create its
own err.h.

Now I'm thinking provide LIBBPF_{IS_ERR,PTR_ERR}(),  in libbpf itself.

>> +	bpf_object__for_each_program(prog, obj) {
>> +		const char *event = bpf_program__title(prog, false);
>> +		int fd, err;
>> +
>> +		LIBBPF_PTR_ASSERT(event, goto errout);
>> +		__LIBBPF_ASSERT(fd = bpf_program__nth_fd(prog, 0),
>> +				>= 0,
>> +				goto errout);
>> +
>> +		if (strncmp(event, "kprobe/", 7) == 0)
>> +			err = create_kprobes(fd, event + 7, true);
>> +		else if (strncmp(event, "kretprobe/", 10) == 0)
>> +			err = create_kprobes(fd, event + 10, false);
> I have a feeling that all bpf+socket, tcbpf1_kernc and trace_output_*.c
> are broken, since I don't see a code that attaches programs to sockets
> and to perf_event.
> How did you test it?

I tested all samples (except tcbpf1_kern, because it is loaded by tc but tc
has not switched to libbpf) in my environment. They are okay for me. There's
no socket attaching code in this patchset because they are in sockex?_user.c
like this:

         obj = load_bpf_file(filename);
         if (!obj)
                 return 1;
         ...
         prog_fd = get_prog_fd(obj, 0);
         ...
         sock = open_raw_sock("lo");

         assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
                           sizeof(prog_fd)) == 0);

And I don't touch the setsockopt in all patches.

>> diff --git a/samples/bpf/utils.h b/samples/bpf/utils.h
>> new file mode 100644
>> index 0000000..5962a68
>> --- /dev/null
>> +++ b/samples/bpf/utils.h
>> @@ -0,0 +1,217 @@
>> +#ifndef __SAMPELS_UTILS_H
>> +#define __SAMPELS_UTILS_H
>> +
>> +#include <bpf/libbpf.h>
>> +#include <bpf/bpf.h>
>> +
>> +/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */
>> +
>> +#define BPF_ALU64_REG(OP, DST, SRC)				\
>> +	((struct bpf_insn) {					\
>> +		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_X,	\
>> +		.dst_reg = DST,					\
>> +		.src_reg = SRC,					\
>> +		.off   = 0,					\
>> +		.imm   = 0 })
> this probably belongs in tools/lib/bpf/bpf.h instead of samples.

Orignally they are macros defined in linux/filter.h. We have 3
filter.h in kernel tree:

include/linux/filter.h
include/uapi/linux/filter.h
tools/include/linux/filter.h

These macros belong to include/linux/filter.h, not part of uapi,
so we have to do things like what we have done for
tools/include/linux/filter.h.

What about moving them into include/uapi/linux/filter.h ? Then
normal user programs like those in samples/bpf can access
them easier.

> The whole set depends on changes in perf/core tree, but
> in net-next we have extra commit 30b50aa612018, so I don't see an easy way
> to route this patch without creating across-tree merge conflicts during
> merge window.
> I'd suggest to apply all required work to tools/lib/bpf/ into perf/core
> and leave samples/bpf/ after merge window.
Good suggestion.

I'll resend them after the PowerPC building breakage fixing is
collected.

Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-17 13:46           ` Daniel Wagner
@ 2015-12-18  3:04             ` Wangnan (F)
  2015-12-18  8:49               ` Daniel Wagner
  0 siblings, 1 reply; 35+ messages in thread
From: Wangnan (F) @ 2015-12-18  3:04 UTC (permalink / raw)
  To: Daniel Wagner, ast, agartrell, acme, bblanco, daniel, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama



On 2015/12/17 21:46, Daniel Wagner wrote:
> On 12/17/2015 11:09 AM, Wangnan (F) wrote:
>> On 2015/12/17 16:29, Daniel Wagner wrote:
>>> On 12/17/2015 08:03 AM, Daniel Wagner wrote:
>>> Patch number 2 didn't apply cleanly.
>> Because I have another patch in my local tree which also modifis bpf
>> Makefile:
>>
>> http://lkml.kernel.org/g/1450316632-152513-1-git-send-email-wangnan0@huawei.com
>>
>> sorry.
> Ah, that explains it this problem.
>
>>> After fixing this manually
>>> I was able to continue to the build step:
>>>
>>> $ make samples/bpf/
>>>     CHK     include/config/kernel.release
>>>     CHK     include/generated/uapi/linux/version.h
>>>     CHK     include/generated/utsrelease.h
>>>     CHK     include/generated/bounds.h
>>>     CHK     include/generated/timeconst.h
>>>     CHK     include/generated/asm-offsets.h
>>>     CALL    scripts/checksyscalls.sh
>>> make -C /home/wagi/src/linux/tools/lib/bpf
>>> O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1
>>> /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
>>> No libelf found
>>> Makefile:203: recipe for target 'elfdep' failed
>>> make[2]: *** [elfdep] Error 255
>>> samples/bpf/Makefile:10: recipe for target
>>> 'samples/bpf/libbpf/libbpf.a' failed
>>> make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
>>> Makefile:1550: recipe for target 'samples/bpf/' failed
>>> make: *** [samples/bpf/] Error 2
>> When you see this, could you please have a look at:
>>
>> /home/wagi/src/linux/samples/bpf/libbpf/feature/test-*.make.output
>>
>> ?
> test-libpython.c:1:20: fatal error: Python.h: No such file or directory

So it is the content in test-all.make.output ? Then it is
not a problem. It is only a fastpath which tries to check
all features by one test. On most platform it would fail.

BPF related feature check is not in test-all. It is a potential
bug, but I don't think it causes your problem.

Another problem is you didn't see this in the first failure:

Auto-detecting system features:
...                        libelf: [ on  ]
...                           bpf: [ on  ]

This only happen when you already have a FEATURE-DUMP.libbpf in that
directory and it is same as the feature check result.

Could you please remove samples/bpf in your building tree and
try again? After you see the failure, what's the content of

/home/wagi/src/linux/samples/bpf/libbpf/FEATURE-* ?

Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18  1:47     ` Wangnan (F)
@ 2015-12-18  6:19       ` Alexei Starovoitov
  2015-12-18  7:04         ` Wangnan (F)
  0 siblings, 1 reply; 35+ messages in thread
From: Alexei Starovoitov @ 2015-12-18  6:19 UTC (permalink / raw)
  To: Wangnan (F)
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama

On Fri, Dec 18, 2015 at 09:47:11AM +0800, Wangnan (F) wrote:
> 
> This is a limitation in tools/lib/bpf/libbpf.h, which has a #include
> <linux/err.h>
> in its header.
> 
> libbpf.h requires this include because its API uses ERR_PTR() to encode
> error code.
> For example, when calling bpf_object__open(), caller should use IS_ERR() to
> check its
> return value instead of compare with NULL, and use PTR_ERR() to retrive
> error number.
> 
> However, linux/err.h is not a part of uapi. To make libbpf work, one has to
> create its
> own err.h.

Why tools/include/linux/err.h is not suitable for everyone?

> Now I'm thinking provide LIBBPF_{IS_ERR,PTR_ERR}(),  in libbpf itself.

seems odd. we already have user space err.h in tools/include.

> And I don't touch the setsockopt in all patches.

ok, but where is the bit that does attach to perf_event to make trace_output work?

> Orignally they are macros defined in linux/filter.h.

no. they were never part of offical filter.h. Only in my earlier versions
of bpf patches, but we decided to drop them before they got into net-next.

> What about moving them into include/uapi/linux/filter.h ? Then
> normal user programs like those in samples/bpf can access
> them easier.

we don't want to add these macros to uapi.
Why not to add it to
tools/include/linux/filter.h
instead?


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18  6:19       ` Alexei Starovoitov
@ 2015-12-18  7:04         ` Wangnan (F)
  2015-12-18  7:10           ` Wangnan (F)
                             ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Wangnan (F) @ 2015-12-18  7:04 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama



On 2015/12/18 14:19, Alexei Starovoitov wrote:
> On Fri, Dec 18, 2015 at 09:47:11AM +0800, Wangnan (F) wrote:
>> This is a limitation in tools/lib/bpf/libbpf.h, which has a #include
>> <linux/err.h>
>> in its header.
>>
>> libbpf.h requires this include because its API uses ERR_PTR() to encode
>> error code.
>> For example, when calling bpf_object__open(), caller should use IS_ERR() to
>> check its
>> return value instead of compare with NULL, and use PTR_ERR() to retrive
>> error number.
>>
>> However, linux/err.h is not a part of uapi. To make libbpf work, one has to
>> create its
>> own err.h.
> Why tools/include/linux/err.h is not suitable for everyone?
>
>> Now I'm thinking provide LIBBPF_{IS_ERR,PTR_ERR}(),  in libbpf itself.
> seems odd. we already have user space err.h in tools/include.

Currently samples/bpf doesn't have an -I$(srctree)/tools/include.

I tried to add it into CFLAGS of samples/bpf. It causes other problems,
This is what I get:

In file included from 
/home/w00229757/kernel-hydrogen/samples/bpf/sock_example.c:27:0:
/usr/include/linux/ip.h:101:2: error: unknown type name ‘__sum16’
   __sum16 check;
   ^
make[3]: *** [samples/bpf/sock_example.o] Error 1
make[2]: *** [samples/bpf/] Error 2
make[1]: *** [sub-make] Error 2
make: *** [__sub-make] Error 2

And after fixing __sum16 in linux/types.h:

   HOSTCC  samples/bpf/tracex4_user.o
   HOSTLD  samples/bpf/tracex4
   HOSTCC  samples/bpf/tracex5_user.o
/kernel/samples/bpf/tracex5_user.c: In function 
‘install_accept_all_seccomp’:
/kernel/samples/bpf/tracex5_user.c:15:21: error: array type has 
incomplete element type
   struct sock_filter filter[] = {
                      ^
/kernel/samples/bpf/tracex5_user.c:16:3: warning: implicit declaration 
of function ‘BPF_STMT’ [-Wimplicit-function-declaration]
    BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
    ^
/kernel/samples/bpf/tracex5_user.c:18:9: error: variable ‘prog’ has 
initializer but incomplete type
   struct sock_fprog prog = {
          ^

Finally we need to add sock_filter, sock_fprog, BPF_STMT into 
tools/include/linux/filter.h.

It is okay, but different from what I really want to do. I'll discuss 
this later.
>> And I don't touch the setsockopt in all patches.
> ok, but where is the bit that does attach to perf_event to make trace_output work?

I didn't change this test_bpf_perf_event() function (only the function 
name).
It creates a bpf-output perf event. This event is inserted into a
BPF_MAP_TYPE_PERF_EVENT_ARRAY by bpf_map_update_elem().

static void test_bpf_perf_event(int map_fd)
{
         struct perf_event_attr attr = {
                 .sample_type = PERF_SAMPLE_RAW,
                 .type = PERF_TYPE_SOFTWARE,
                 .config = PERF_COUNT_SW_BPF_OUTPUT,
         };
         int key = 0;

         pmu_fd = perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, 
-1/*group_fd*/, 0);

         assert(pmu_fd >= 0);
         assert(bpf_map_update_elem(map_fd, &key, &pmu_fd, BPF_ANY) == 0);
         ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
}

And you read from this pmu_fd, get results. The logical is unchanged.

>
>> Orignally they are macros defined in linux/filter.h.
> no. they were never part of offical filter.h. Only in my earlier versions
> of bpf patches, but we decided to drop them before they got into net-next.
>
>> What about moving them into include/uapi/linux/filter.h ? Then
>> normal user programs like those in samples/bpf can access
>> them easier.
> we don't want to add these macros to uapi.
> Why not to add it to
> tools/include/linux/filter.h
> instead?

What I want to do in this patchset is not only removing original libbpf.c
and bpf_load.c. In fact I want libbpf in tools/lib/bpf becomes a public
available library for other userspace tools (tc for example). Switching
samples/bpf into libbpf is the first step of this goal. From doing this
I found and fixed some limitation, like those missed BPF map operations.
Making libbpf.h and bpf.h available for normal userspace programs is also
important.

Having the above goal, I think you can understand why improving 
tools/include
is not a good idea. You don't want to force a normal userspace program setup
a similar header environment for using libbpf. It is relatively a small
library. So it would be good if bpf.h and libbpf.h only depend on what can
be found in uapi.

Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18  7:04         ` Wangnan (F)
@ 2015-12-18  7:10           ` Wangnan (F)
  2015-12-18 10:57           ` Daniel Borkmann
  2015-12-19  0:35           ` Alexei Starovoitov
  2 siblings, 0 replies; 35+ messages in thread
From: Wangnan (F) @ 2015-12-18  7:10 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama



On 2015/12/18 15:04, Wangnan (F) wrote:
>
>
> On 2015/12/18 14:19, Alexei Starovoitov wrote:
>> On Fri, Dec 18, 2015 at 09:47:11AM +0800, Wangnan (F) wrote:
>>> This is a limitation in tools/lib/bpf/libbpf.h, which has a #include
>>> <linux/err.h>
>>> in its header.
>>>
>>> libbpf.h requires this include because its API uses ERR_PTR() to encode
>>> error code.
>>> For example, when calling bpf_object__open(), caller should use 
>>> IS_ERR() to
>>> check its
>>> return value instead of compare with NULL, and use PTR_ERR() to retrive
>>> error number.
>>>
>>> However, linux/err.h is not a part of uapi. To make libbpf work, one 
>>> has to
>>> create its
>>> own err.h.
>>
[SNIP]
>>> What about moving them into include/uapi/linux/filter.h ? Then
>>> normal user programs like those in samples/bpf can access
>>> them easier.
>> we don't want to add these macros to uapi.
>> Why not to add it to
>> tools/include/linux/filter.h
>> instead?
>
> What I want to do in this patchset is not only removing original libbpf.c
> and bpf_load.c. In fact I want libbpf in tools/lib/bpf becomes a public
> available library for other userspace tools (tc for example). Switching
> samples/bpf into libbpf is the first step of this goal. From doing this
> I found and fixed some limitation, like those missed BPF map operations.
> Making libbpf.h and bpf.h available for normal userspace programs is also
> important.
>
> Having the above goal, I think you can understand why improving 
> tools/include
> is not a good idea. You don't want to force a normal userspace program 
> setup
> a similar header environment for using libbpf. It is relatively a small
> library. So it would be good if bpf.h and libbpf.h only depend on what 
> can
> be found in uapi.
>

I suddenly realized that only linux/err.h causes problem. Those macros from
filter.h are never accessed by libbpf. So we can drop those filter.h by 
making
samples/bpf include from tools/include. However we still need a wrapper in
libbpf to avoid including linux/err.h.

Thank you.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-18  3:04             ` Wangnan (F)
@ 2015-12-18  8:49               ` Daniel Wagner
  2015-12-18 10:56                 ` [PATCH] tools build: Output more data during feature detection Wang Nan
  2015-12-18 11:03                 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wangnan (F)
  0 siblings, 2 replies; 35+ messages in thread
From: Daniel Wagner @ 2015-12-18  8:49 UTC (permalink / raw)
  To: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

On 12/18/2015 04:04 AM, Wangnan (F) wrote:
> On 2015/12/17 21:46, Daniel Wagner wrote:
>> On 12/17/2015 11:09 AM, Wangnan (F) wrote:
>>> On 2015/12/17 16:29, Daniel Wagner wrote:
>>>> On 12/17/2015 08:03 AM, Daniel Wagner wrote:
>>>> Patch number 2 didn't apply cleanly.
>>> When you see this, could you please have a look at:
>>>
>>> /home/wagi/src/linux/samples/bpf/libbpf/feature/test-*.make.output
>>>
>>> ?
>> test-libpython.c:1:20: fatal error: Python.h: No such file or directory
> 
> So it is the content in test-all.make.output ? Then it is
> not a problem. It is only a fastpath which tries to check
> all features by one test. On most platform it would fail.

I see. 

> BPF related feature check is not in test-all. It is a potential
> bug, but I don't think it causes your problem.
> 
> Another problem is you didn't see this in the first failure:
> 
> Auto-detecting system features:
> ...                        libelf: [ on  ]
> ...                           bpf: [ on  ]
> 
> This only happen when you already have a FEATURE-DUMP.libbpf in that
> directory and it is same as the feature check result.
> 
> Could you please remove samples/bpf in your building tree and
> try again? After you see the failure, what's the content of
> 
> /home/wagi/src/linux/samples/bpf/libbpf/FEATURE-* ?

I cleanup up my tree (rm samples/bpf/ and git checkout samples/bpf) and then

$ make samples/bpf/ 
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  LD      samples/bpf/built-in.o
make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a

Auto-detecting system features:
...                        libelf: [ OFF ]
...                           bpf: [ OFF ]

No libelf found
Makefile:203: recipe for target 'elfdep' failed
make[2]: *** [elfdep] Error 255
samples/bpf/Makefile:10: recipe for target 'samples/bpf/libbpf/libbpf.a' failed
make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
Makefile:1550: recipe for target 'samples/bpf/' failed
make: *** [samples/bpf/] Error 2

$ cat /home/wagi/src/linux/samples/bpf/libbpf/FEATURE-*
feature-libelf(0) feature-bpf(0)

$ make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
make: Entering directory '/home/wagi/src/linux/tools/lib/bpf'

Auto-detecting system features:
...                        libelf: [ on  ]
...                           bpf: [ on  ]

make -f /home/wagi/src/linux/tools/build/Makefile.build dir=. obj=libbpf
  gcc -Wp,-MD,/home/wagi/src/linux/samples/bpf/libbpf/.libbpf.o.d,-MT,/home/wagi/src/linux/samples/bpf/libbpf/libbpf.o  -DHAVE_LIBELF_MMAP_SUPPORT -DHAVE_ELF_GETPHDRNUM_SUPPORT -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wshadow -Wstrict-aliasing=3 -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Werror -Wall -fPIC -I. -I/home/wagi/src/linux/tools/include -I/home/wagi/src/linux/arch//include/uapi -I/home/wagi/src/linux/include/uapi -D"BUILD_STR(s)=#s"   -c -o /home/wagi/src/linux/samples/bpf/libbpf/libbpf.o libbpf.c
  gcc -Wp,-MD,/home/wagi/src/linux/samples/bpf/libbpf/.bpf.o.d,-MT,/home/wagi/src/linux/samples/bpf/libbpf/bpf.o  -DHAVE_LIBELF_MMAP_SUPPORT -DHAVE_ELF_GETPHDRNUM_SUPPORT -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wshadow -Wstrict-aliasing=3 -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Werror -Wall -fPIC -I. -I/home/wagi/src/linux/tools/include -I/home/wagi/src/linux/arch//include/uapi -I/home/wagi/src/linux/include/uapi -D"BUILD_STR(s)=#s"   -c -o /home/wagi/src/linux/samples/bpf/libbpf/bpf.o bpf.c
   ld -r -o /home/wagi/src/linux/samples/bpf/libbpf/libbpf-in.o  /home/wagi/src/linux/samples/bpf/libbpf/libbpf.o /home/wagi/src/linux/samples/bpf/libbpf/bpf.o
rm -f /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a; ar rcs /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a /home/wagi/src/linux/samples/bpf/libbpf/libbpf-in.o
make: Leaving directory '/home/wagi/src/linux/tools/lib/bpf' 

$  make samples/bpf/
  CHK     include/config/kernel.release
  CHK     include/generated/uapi/linux/version.h
  CHK     include/generated/utsrelease.h
  CHK     include/generated/bounds.h
  CHK     include/generated/timeconst.h
  CHK     include/generated/asm-offsets.h
  CALL    scripts/checksyscalls.sh
  HOSTCC  samples/bpf/test_verifier.o
  HOSTLD  samples/bpf/test_verifier
  HOSTCC  samples/bpf/test_maps.o
  HOSTLD  samples/bpf/test_maps
  HOSTCC  samples/bpf/sock_example.o
  HOSTCC  samples/bpf/utils.o
  HOSTLD  samples/bpf/sock_example
  HOSTCC  samples/bpf/fds_example.o
  HOSTLD  samples/bpf/fds_example
  HOSTCC  samples/bpf/sockex1_user.o
  HOSTLD  samples/bpf/sockex1
  HOSTCC  samples/bpf/sockex2_user.o
  HOSTLD  samples/bpf/sockex2
  HOSTCC  samples/bpf/sockex3_user.o
  HOSTLD  samples/bpf/sockex3
  HOSTCC  samples/bpf/tracex1_user.o
  HOSTLD  samples/bpf/tracex1
  HOSTCC  samples/bpf/tracex2_user.o
  HOSTLD  samples/bpf/tracex2
  HOSTCC  samples/bpf/tracex3_user.o
  HOSTLD  samples/bpf/tracex3
  HOSTCC  samples/bpf/tracex4_user.o
  HOSTLD  samples/bpf/tracex4
  HOSTCC  samples/bpf/tracex5_user.o
  HOSTLD  samples/bpf/tracex5
  HOSTCC  samples/bpf/tracex6_user.o
  HOSTLD  samples/bpf/tracex6
  HOSTCC  samples/bpf/trace_output_user.o
  HOSTLD  samples/bpf/trace_output
  HOSTCC  samples/bpf/lathist_user.o
  HOSTLD  samples/bpf/lathist
clang  -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/5.1.1/include -I./arch/x86/include -Iarch/x86/include/generated/uapi -Iarch/x86/include/generated  -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h  \
        -D__KERNEL__ -D__ASM_SYSREG_H -Wno-unused-value -Wno-pointer-sign \
        -O2 -emit-llvm -c samples/bpf/sockex1_kern.c -o -| ./tools/bpf/llvm/bld/Debug+Asserts/bin/llc -march=bpf -filetype=obj -o samples/bpf/sockex1_kern.o
/bin/sh: line 2: ./tools/bpf/llvm/bld/Debug+Asserts/bin/llc: No such file or directory
clang: error: unable to execute command: Broken pipe
clang: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /tmp/sockex1_kern-d40fee.c
clang: note: diagnostic msg: /tmp/sockex1_kern-d40fee.sh
clang: note: diagnostic msg: 

********************
samples/bpf/Makefile:83: recipe for target 'samples/bpf/sockex1_kern.o' failed
make[1]: *** [samples/bpf/sockex1_kern.o] Error 127
Makefile:1550: recipe for target 'samples/bpf/' failed


So the last error is clear. llc is missing I need to rebuild it. 
There is something funny going on for the first call 'make samples/bpf/'. 

^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH] tools build: Output more data during feature detection
  2015-12-18  8:49               ` Daniel Wagner
@ 2015-12-18 10:56                 ` Wang Nan
  2015-12-18 11:03                 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wangnan (F)
  1 sibling, 0 replies; 35+ messages in thread
From: Wang Nan @ 2015-12-18 10:56 UTC (permalink / raw)
  To: daniel.wagner; +Cc: linux-kernel, pi3orama, Wang Nan, Jiri Olsa

Even with current '.make.output' finding the root cause for missing
feature is not enough. This patch adds extra information to
.make.output. It also creates a .make.makeoutput to collect output of
'make'.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 tools/build/Makefile.feature | 4 ++--
 tools/build/feature/Makefile | 7 ++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 6c0519d..84927df 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -1,13 +1,13 @@
 feature_dir := $(srctree)/tools/build/feature
 
 ifneq ($(OUTPUT),)
-  OUTPUT_FEATURES = $(OUTPUT)feature/
+  OUTPUT_FEATURES = $(OUTPUT)feature$(FEATURE_USER)/
   $(shell mkdir -p $(OUTPUT_FEATURES))
 endif
 
 feature_check = $(eval $(feature_check_code))
 define feature_check_code
-  feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
+  feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >$(OUTPUT_FEATURES)test-$1.make.makeoutput 2>&1 && echo 1 || echo 0)
 endef
 
 feature_set = $(eval $(feature_set_code))
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index bf8f035..842973a 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -45,7 +45,12 @@ PKG_CONFIG := $(CROSS_COMPILE)pkg-config
 all: $(FILES)
 
 __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $@ $(patsubst %.bin,%.c,$(@F)) $(LDFLAGS)
-  BUILD = $(__BUILD) > $(@:.bin=.make.output) 2>&1
+  BUILD = echo PWD=$(shell pwd) > $(@:.bin=.make.output); \
+	  echo PATH=$$PATH >> $(@:.bin=.make.output); \
+	  echo CFLAGS=$$CFLAGS >> $(@:.bin=.make.output); \
+	  echo LDFLAGS=$$LDFLAGS >> $(@:.bin=.make.output); \
+	  echo '$(__BUILD)' >> $(@:.bin=.make.output) ; \
+	  $(__BUILD) >> $(@:.bin=.make.output) 2>&1
 
 ###############################
 
-- 
1.8.3.4


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18  7:04         ` Wangnan (F)
  2015-12-18  7:10           ` Wangnan (F)
@ 2015-12-18 10:57           ` Daniel Borkmann
  2015-12-18 11:18             ` pi3orama
  2015-12-19  0:35           ` Alexei Starovoitov
  2 siblings, 1 reply; 35+ messages in thread
From: Daniel Borkmann @ 2015-12-18 10:57 UTC (permalink / raw)
  To: Wangnan (F), Alexei Starovoitov
  Cc: ast, agartrell, acme, bblanco, daniel.wagner, davem, mingo,
	jolsa, xiakaixu, holzheu, yang.shi, linux-kernel, pi3orama

On 12/18/2015 08:04 AM, Wangnan (F) wrote:
...
> What I want to do in this patchset is not only removing original libbpf.c
> and bpf_load.c. In fact I want libbpf in tools/lib/bpf becomes a public
> available library for other userspace tools (tc for example).

Having this as a possible user space library seems fine.

Only speaking for the tc case specifically here (since you mention it as
one example), there's currently no additional value for it. The current
loader code there is functional and partially tailored for tc's needs and
having this together with the iproute2 repo, it allows us to easily change/
adapt the internal code whenever needed.

The only dependency the loader code has is that the BPF syscall got compiled
into the kernel and libelf, that's all. libelf is effectively available
in distros for more than a decade(s?). And iproute2 is being shipped
everywhere already as well (hence also iproute2's minimalism on library
dependencies).

Switching that code would mean that iproute2 would then depend on libbpf
which itself would depend on libelf, until every distro that ships iproute2
will also ship libbpf, it will take a bit. Changes on the code would then
need to go through libbpf first, and iproute2 would need to wait until it
becomes available to make use of it and probably need to implement some
compat code for the time being. Further, as both are decoupled also testing
effort increases to make sure nothing breaks among different versions.

That said, I prefer that tc's {cls,act}_bpf front-end is shipped to users
as it's being done already and that they can use it /now/ as-is. Don't get me
wrong, for other tools etc coming up in future, as mentioned, offering it as a
public library makes totally sense as not every application developer would
want to choose writing his own loader code.

Cheers,
Daniel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-18  8:49               ` Daniel Wagner
  2015-12-18 10:56                 ` [PATCH] tools build: Output more data during feature detection Wang Nan
@ 2015-12-18 11:03                 ` Wangnan (F)
  2015-12-18 12:55                   ` Daniel Wagner
  1 sibling, 1 reply; 35+ messages in thread
From: Wangnan (F) @ 2015-12-18 11:03 UTC (permalink / raw)
  To: Daniel Wagner, ast, agartrell, acme, bblanco, daniel, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama



On 2015/12/18 16:49, Daniel Wagner wrote:
> On 12/18/2015 04:04 AM, Wangnan (F) wrote:
>> On 2015/12/17 21:46, Daniel Wagner wrote:
>>> On 12/17/2015 11:09 AM, Wangnan (F) wrote:
>>>> On 2015/12/17 16:29, Daniel Wagner wrote:
>>>>> On 12/17/2015 08:03 AM, Daniel Wagner wrote:
>>>>> Patch number 2 didn't apply cleanly.
>>>> When you see this, could you please have a look at:
>>>>
>>>> /home/wagi/src/linux/samples/bpf/libbpf/feature/test-*.make.output
>>>>
>>>> ?
>>> test-libpython.c:1:20: fatal error: Python.h: No such file or directory
>> So it is the content in test-all.make.output ? Then it is
>> not a problem. It is only a fastpath which tries to check
>> all features by one test. On most platform it would fail.
> I see.
>
>> BPF related feature check is not in test-all. It is a potential
>> bug, but I don't think it causes your problem.
>>
>> Another problem is you didn't see this in the first failure:
>>
>> Auto-detecting system features:
>> ...                        libelf: [ on  ]
>> ...                           bpf: [ on  ]
>>
>> This only happen when you already have a FEATURE-DUMP.libbpf in that
>> directory and it is same as the feature check result.
>>
>> Could you please remove samples/bpf in your building tree and
>> try again? After you see the failure, what's the content of
>>
>> /home/wagi/src/linux/samples/bpf/libbpf/FEATURE-* ?
> I cleanup up my tree (rm samples/bpf/ and git checkout samples/bpf) and then
>
> $ make samples/bpf/
>    CHK     include/config/kernel.release
>    CHK     include/generated/uapi/linux/version.h
>    CHK     include/generated/utsrelease.h
>    CHK     include/generated/bounds.h
>    CHK     include/generated/timeconst.h
>    CHK     include/generated/asm-offsets.h
>    CALL    scripts/checksyscalls.sh
>    LD      samples/bpf/built-in.o
> make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a
>
> Auto-detecting system features:
> ...                        libelf: [ OFF ]
> ...                           bpf: [ OFF ]

That's good. This is not a magic. I guess something in your top makefile
causes this feature check failure. I sent a patch on feature checker to you.
It will appear as [1] soon. Could you please apply it and try again?

This time you will see test-*.make.output and test-*.make.makeoutput.
test-*.make.output lists your PATH, PWD and the gcc command you use for
feature check. test-*.make.makeoutput is the output of 'make' itself. I 
think
from these information we can find the root cause easier.

Thank you.

[1] 
http://lkml.kernel.org/g/1450436211-170447-1-git-send-email-wangnan0@huawei.com




^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18 10:57           ` Daniel Borkmann
@ 2015-12-18 11:18             ` pi3orama
  2015-12-18 11:24               ` Daniel Borkmann
  0 siblings, 1 reply; 35+ messages in thread
From: pi3orama @ 2015-12-18 11:18 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: Wangnan (F),
	Alexei Starovoitov, ast, agartrell, acme, bblanco, daniel.wagner,
	davem, mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel



发自我的 iPhone

> 在 2015年12月18日,下午6:57,Daniel Borkmann <daniel@iogearbox.net> 写道:
> 
>> On 12/18/2015 08:04 AM, Wangnan (F) wrote:
>> ...
>> What I want to do in this patchset is not only removing original libbpf.c
>> and bpf_load.c. In fact I want libbpf in tools/lib/bpf becomes a public
>> available library for other userspace tools (tc for example).
> 
> Having this as a possible user space library seems fine.
> 
> Only speaking for the tc case specifically here (since you mention it as
> one example), there's currently no additional value for it. The current
> loader code there is functional and partially tailored for tc's needs and
> having this together with the iproute2 repo, it allows us to easily change/
> adapt the internal code whenever needed.
> 
> The only dependency the loader code has is that the BPF syscall got compiled
> into the kernel and libelf, that's all. libelf is effectively available
> in distros for more than a decade(s?). And iproute2 is being shipped
> everywhere already as well (hence also iproute2's minimalism on library
> dependencies).
> 
> Switching that code would mean that iproute2 would then depend on libbpf
> which itself would depend on libelf, until every distro that ships iproute2
> will also ship libbpf, it will take a bit. Changes on the code would then
> need to go through libbpf first, and iproute2 would need to wait until it
> becomes available to make use of it and probably need to implement some
> compat code for the time being. Further, as both are decoupled also testing
> effort increases to make sure nothing breaks among different versions.
> 
> That said, I prefer that tc's {cls,act}_bpf front-end is shipped to users
> as it's being done already and that they can use it /now/ as-is. Don't get me
> wrong, for other tools etc coming up in future, as mentioned, offering it as a
> public library makes totally sense as not every application developer would
> want to choose writing his own loader code.
> 

Get it, and I remember you told me about this once.

There's another goal. When someone introduces new functions to eBPF, like
object pin added in these days, switching samples to libbpf will lead he/she
to help me improve libbpf, because if a new sample is needed, the libbpf backend
must be update correspondingly :)

> Cheers,
> Daniel


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18 11:18             ` pi3orama
@ 2015-12-18 11:24               ` Daniel Borkmann
  0 siblings, 0 replies; 35+ messages in thread
From: Daniel Borkmann @ 2015-12-18 11:24 UTC (permalink / raw)
  To: pi3orama
  Cc: Wangnan (F),
	Alexei Starovoitov, ast, agartrell, acme, bblanco, daniel.wagner,
	davem, mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel

On 12/18/2015 12:18 PM, pi3orama wrote:
...
> Get it, and I remember you told me about this once.
>
> There's another goal. When someone introduces new functions to eBPF, like
> object pin added in these days, switching samples to libbpf will lead he/she
> to help me improve libbpf, because if a new sample is needed, the libbpf backend
> must be update correspondingly :)

Yep, that's good and makes sense.

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-18 11:03                 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wangnan (F)
@ 2015-12-18 12:55                   ` Daniel Wagner
  2015-12-18 14:13                     ` pi3orama
       [not found]                     ` <66E52D4A-BA1C-456A-8E6F-975E07C083EE@163.com>
  0 siblings, 2 replies; 35+ messages in thread
From: Daniel Wagner @ 2015-12-18 12:55 UTC (permalink / raw)
  To: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi
  Cc: linux-kernel, pi3orama

On 12/18/2015 12:03 PM, Wangnan (F) wrote:
> That's good. This is not a magic.

That is what you say! :)

> I guess something in your top makefile
> causes this feature check failure. I sent a patch on feature checker to
> you.
> It will appear as [1] soon. Could you please apply it and try again?

Sure.

> This time you will see test-*.make.output and test-*.make.makeoutput.
> test-*.make.output lists your PATH, PWD and the gcc command you use for
> feature check. test-*.make.makeoutput is the output of 'make' itself. I
> think
> from these information we can find the root cause easier.

$ ls samples/bpf/libbpf/feature.libbpf/*
samples/bpf/libbpf/feature.libbpf/test-all.make.makeoutput
samples/bpf/libbpf/feature.libbpf/test-bpf.make.makeoutput
samples/bpf/libbpf/feature.libbpf/test-libelf-getphdrnum.make.makeoutput
samples/bpf/libbpf/feature.libbpf/test-libelf.make.makeoutput
samples/bpf/libbpf/feature.libbpf/test-libelf-mmap.make.makeoutput

$ cat samples/bpf/libbpf/feature.libbpf/*
make[2]: *** tools/build/feature: No such file or directory.  Stop.
make[2]: *** tools/build/feature: No such file or directory.  Stop.
make[2]: *** tools/build/feature: No such file or directory.  Stop.
make[2]: *** tools/build/feature: No such file or directory.  Stop.
make[2]: *** tools/build/feature: No such file or directory.  Stop.

$ find -name *.make.output
./tools/build/feature/test-gtk2.make.output
./tools/build/feature/test-libpython.make.output
./tools/build/feature/test-libunwind.make.output
./tools/build/feature/test-bionic.make.output
./tools/build/feature/test-libelf-mmap.make.output
./tools/build/feature/test-numa_num_possible_cpus.make.output
./tools/build/feature/test-libaudit.make.output
./tools/build/feature/test-libslang.make.output
./tools/build/feature/test-libdw-dwarf-unwind.make.output
./tools/build/feature/test-libbfd.make.output
./tools/build/feature/test-get_cpuid.make.output
./tools/build/feature/test-zlib.make.output
./tools/build/feature/test-libelf.make.output
./tools/build/feature/test-libperl.make.output
./tools/build/feature/test-bpf.make.output
./tools/build/feature/test-dwarf.make.output
./tools/build/feature/test-libnuma.make.output
./tools/build/feature/test-glibc.make.output
./tools/build/feature/test-cplus-demangle.make.output
./tools/build/feature/test-libelf-getphdrnum.make.output
./tools/build/feature/test-all.make.output
./tools/build/feature/test-lzma.make.output


$ ls -l  tools/build/feature/*.make.output
-rw-rw-r-- 1 wagi wagi 419 Dec 17 14:39 tools/build/feature/test-all.make.output
-rw-rw-r-- 1 wagi wagi 104 Oct 20 09:59 tools/build/feature/test-bionic.make.output
-rw-rw-r-- 1 wagi wagi   0 Dec 17 09:01 tools/build/feature/test-bpf.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-cplus-demangle.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-dwarf.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-get_cpuid.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-glibc.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-gtk2.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libaudit.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libbfd.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libdw-dwarf-unwind.make.output
-rw-rw-r-- 1 wagi wagi   0 Dec 17 09:01 tools/build/feature/test-libelf-getphdrnum.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libelf.make.output
-rw-rw-r-- 1 wagi wagi   0 Dec 17 09:01 tools/build/feature/test-libelf-mmap.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libnuma.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libperl.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libpython.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libslang.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-libunwind.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-lzma.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-numa_num_possible_cpus.make.output
-rw-rw-r-- 1 wagi wagi   0 Oct 20 09:59 tools/build/feature/test-zlib.make.output

$ cat tools/build/feature/test-all.make.output
In file included from /usr/include/Python.h:7:0,
                 from test-libpython.c:1,
                 from test-all.c:13:
/usr/lib64/perl5/CORE/patchlevel.h:135:2: error: ‘NULL’ undeclared here (not in a function)
  NULL
  ^
In file included from test-libpython.c:1:0,
                 from test-all.c:13:
/usr/include/Python.h:8:22: fatal error: pyconfig.h: No such file or directory
compilation terminated.

$ cat tools/build/feature/test-bionic.make.output
test-bionic.c:1:31: fatal error: android/api-level.h: No such file or directory
compilation terminated.


Could it be that $(srcdir) somehow is not correct? I exchanged

	feature_dir := $(srctree)/tools/build/feature
to
	feature_dir := /home/wagi/src/linux/tools/build/feature

and then the feature check worked in this case but still no fun:


$ make samples/bpf/
CHK include/config/kernel.release
CHK include/generated/uapi/linux/version.h
CHK include/generated/utsrelease.h
CHK include/generated/bounds.h
CHK include/generated/timeconst.h
CHK include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
make -C /home/wagi/src/linux/tools/lib/bpf O=/home/wagi/src/linux/samples/bpf/libbpf CFLAGS= LDFLAGS= V=1 /home/wagi/src/linux/samples/bpf/libbpf/libbpf.a

Auto-detecting system features:
... libelf: [ on ]
... bpf: [ on ]

make -f ./tools/build/Makefile.build dir=. obj=libbpf
make[3]: tools/build/Makefile.build: No such file or directory
make[3]: *** No rule to make target 'tools/build/Makefile.build'. Stop.
Makefile:155: recipe for target '/home/wagi/src/linux/samples/bpf/libbpf/libbpf-in.o' failed
make[2]: *** [/home/wagi/src/linux/samples/bpf/libbpf/libbpf-in.o] Error 2
samples/bpf/Makefile:10: recipe for target 'samples/bpf/libbpf/libbpf.a' failed
make[1]: *** [samples/bpf/libbpf/libbpf.a] Error 2
Makefile:1550: recipe for target 'samples/bpf/' failed
make: *** [samples/bpf/] Error 2

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
  2015-12-18 12:55                   ` Daniel Wagner
@ 2015-12-18 14:13                     ` pi3orama
       [not found]                     ` <66E52D4A-BA1C-456A-8E6F-975E07C083EE@163.com>
  1 sibling, 0 replies; 35+ messages in thread
From: pi3orama @ 2015-12-18 14:13 UTC (permalink / raw)
  To: Daniel Wagner
  Cc: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi, linux-kernel



发自我的 iPhone

> 在 2015年12月18日,下午8:55,Daniel Wagner <daniel.wagner@bmw-carit.de> 写道:
> 
>> On 12/18/2015 12:03 PM, Wangnan (F) wrote:
>> That's good. This is not a magic.
> 
> That is what you say! :)
> 
>> I guess something in your top makefile
>> causes this feature check failure. I sent a patch on feature checker to
>> you.
>> It will appear as [1] soon. Could you please apply it and try again?
> 
> Sure.
> 
>> This time you will see test-*.make.output and test-*.make.makeoutput.
>> test-*.make.output lists your PATH, PWD and the gcc command you use for
>> feature check. test-*.make.makeoutput is the output of 'make' itself. I
>> think
>> from these information we can find the root cause easier.
> 
> $ ls samples/bpf/libbpf/feature.libbpf/*
> samples/bpf/libbpf/feature.libbpf/test-all.make.makeoutput
> samples/bpf/libbpf/feature.libbpf/test-bpf.make.makeoutput
> samples/bpf/libbpf/feature.libbpf/test-libelf-getphdrnum.make.makeoutput
> samples/bpf/libbpf/feature.libbpf/test-libelf.make.makeoutput
> samples/bpf/libbpf/feature.libbpf/test-libelf-mmap.make.makeoutput
> 
> $ cat samples/bpf/libbpf/feature.libbpf/*
> make[2]: *** tools/build/feature: No such file or directory.  Stop.
> make[2]: *** tools/build/feature: No such file or directory.  Stop.
> make[2]: *** tools/build/feature: No such file or directory.  Stop.
> make[2]: *** tools/build/feature: No such file or directory.  Stop.
> make[2]: *** tools/build/feature: No such file or directory.  Stop.
> 

Thank you for your information.

I think the reason of the failure is the missing of srctree. I skipped a patch [1]
because I think it is independent with this patchset, but I was wrong.

Could you please add the srctree setting code block from [1] to your
tools/lib/bpf/Makefile and try again? You don't need other part of it,
or you have to apply the whole patchset because it moves a file.

[1] http://lkml.kernel.org/g/1450316632-152513-1-git-send-email-wangnan0@huawei.com

Thank you.



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations
       [not found]                     ` <66E52D4A-BA1C-456A-8E6F-975E07C083EE@163.com>
@ 2015-12-18 14:22                       ` Daniel Wagner
  0 siblings, 0 replies; 35+ messages in thread
From: Daniel Wagner @ 2015-12-18 14:22 UTC (permalink / raw)
  To: pi3orama
  Cc: Wangnan (F),
	ast, agartrell, acme, bblanco, daniel, davem, mingo, jolsa,
	xiakaixu, holzheu, yang.shi, linux-kernel

On 12/18/2015 02:50 PM, pi3orama wrote:
>> Could it be that $(srcdir) somehow is not correct? I exchanged
>>
>>    feature_dir := $(srctree)/tools/build/feature
>> to
>>    feature_dir := /home/wagi/src/linux/tools/build/feature
>>
> 
> Can you remember the patch set I skipped?
> 
> http://lkml.kernel.org/g/1450316632-152513-4-git-send-email-wangnan0@huawei.com
> <http://lkml.kernel.org/g/1450316632-152513-1-git-send-email-wangnan0@huawei.com>

I'll give them a try next week.

> I thought that patch set is independent with this one but I was wrong.
> The reason
> of your problem is the missing of srctree. Could you please add the
> definition of
> srctree and try again? Like this:
> 
> +ifeq ($(srctree),)
> +srctree := $(patsubst %/,%,$(dir $(shell pwd)))
> +srctree := $(patsubst %/,%,$(dir $(srctree)))
> +srctree := $(patsubst %/,%,$(dir $(srctree)))
> +#$(info Determined 'srctree' to be $(srctree))
> +endif
> 
> At the head of tools/lib/bpf/Makefile

I tried that one but it didn't change unfortunately. I saw that code
snipped is already in tools/lib/bpf/Makefile line 62. It exists since

1b76c13e4b36 ("bpf tools: Introduce 'bpf' library and add bpf feature
check")


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF
  2015-12-18  7:04         ` Wangnan (F)
  2015-12-18  7:10           ` Wangnan (F)
  2015-12-18 10:57           ` Daniel Borkmann
@ 2015-12-19  0:35           ` Alexei Starovoitov
  2 siblings, 0 replies; 35+ messages in thread
From: Alexei Starovoitov @ 2015-12-19  0:35 UTC (permalink / raw)
  To: Wangnan (F)
  Cc: ast, agartrell, acme, bblanco, daniel, daniel.wagner, davem,
	mingo, jolsa, xiakaixu, holzheu, yang.shi, linux-kernel,
	pi3orama

On Fri, Dec 18, 2015 at 03:04:00PM +0800, Wangnan (F) wrote:
> 
> >>However, linux/err.h is not a part of uapi. To make libbpf work, one has to
> >>create its
> >>own err.h.
> >Why tools/include/linux/err.h is not suitable for everyone?
> >
> >>Now I'm thinking provide LIBBPF_{IS_ERR,PTR_ERR}(),  in libbpf itself.
> >seems odd. we already have user space err.h in tools/include.
> 
> Currently samples/bpf doesn't have an -I$(srctree)/tools/include.
> 
> I tried to add it into CFLAGS of samples/bpf. It causes other problems,

let's fix those problem then.

> What I want to do in this patchset is not only removing original libbpf.c
> and bpf_load.c. In fact I want libbpf in tools/lib/bpf becomes a public
> available library for other userspace tools (tc for example). Switching
> samples/bpf into libbpf is the first step of this goal. From doing this
> I found and fixed some limitation, like those missed BPF map operations.
> Making libbpf.h and bpf.h available for normal userspace programs is also
> important.
> 
> Having the above goal, I think you can understand why improving
> tools/include
> is not a good idea. You don't want to force a normal userspace program setup
> a similar header environment for using libbpf. It is relatively a small
> library. So it would be good if bpf.h and libbpf.h only depend on what can
> be found in uapi.

completely agree on the goal of making libbpf to be a standalone library,
but disagree on tools/include dependency.
If you copy-paste err.h into libbpf either as-is or as LIBBPF_IS_ERR,
it's not going to be enough. Soon you'll need another macro from tools/include
and so on. imo it's much easier to include tools/include/ as part of
standalone libbpf.

Also at the time of creation of tools/lib/bpf we agreed that it's LGPL
just like tools/lib/traceevent, but I don't see any mention of it in
the libbpf source.


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2015-12-19  0:35 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-17  5:23 [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wang Nan
2015-12-17  5:23 ` [PATCH 01/10] bpf samples: bpf: Fix tracex5_kern.c compiling error Wang Nan
2015-12-17  5:23 ` [PATCH 02/10] bpf tools: Define LD and RM in Makefile for 'make -R' Wang Nan
2015-12-17  5:23 ` [PATCH 03/10] bpf tools: Add const decoretor to 'license' and 'insns' for bpf_load_program() Wang Nan
2015-12-17  5:23 ` [PATCH 04/10] bpf tools: Switch to uapi style type names Wang Nan
2015-12-17  5:23 ` [PATCH 05/10] bpf tools: Support load different type of programs Wang Nan
2015-12-17  5:23 ` [PATCH 06/10] bpf tools: Support new map operations Wang Nan
2015-12-17  6:06   ` Wangnan (F)
2015-12-17  6:09   ` [PATCH v2 " Wang Nan
2015-12-17  5:23 ` [PATCH 07/10] bpf tools: Support BPF_OBJ_PIN and BPF_OBJ_GET Wang Nan
2015-12-17  5:23 ` [PATCH 08/10] bpf samples: Add utils.[ch] for using BPF Wang Nan
2015-12-17 23:11   ` Alexei Starovoitov
2015-12-18  1:47     ` Wangnan (F)
2015-12-18  6:19       ` Alexei Starovoitov
2015-12-18  7:04         ` Wangnan (F)
2015-12-18  7:10           ` Wangnan (F)
2015-12-18 10:57           ` Daniel Borkmann
2015-12-18 11:18             ` pi3orama
2015-12-18 11:24               ` Daniel Borkmann
2015-12-19  0:35           ` Alexei Starovoitov
2015-12-17  5:23 ` [PATCH 09/10] bpf samples: Uses libbpf in tools/lib to deal with BPF operations Wang Nan
2015-12-17  5:23 ` [PATCH 10/10] bpf samples: Remove old BPF helpers Wang Nan
2015-12-17  6:38 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Daniel Wagner
2015-12-17  6:51   ` Wangnan (F)
2015-12-17  7:03     ` Daniel Wagner
2015-12-17  8:29       ` Daniel Wagner
2015-12-17 10:09         ` Wangnan (F)
2015-12-17 13:46           ` Daniel Wagner
2015-12-18  3:04             ` Wangnan (F)
2015-12-18  8:49               ` Daniel Wagner
2015-12-18 10:56                 ` [PATCH] tools build: Output more data during feature detection Wang Nan
2015-12-18 11:03                 ` [PATCH 00/10] bpf samples: Uses libbpf in tools/lib to do BPF operations Wangnan (F)
2015-12-18 12:55                   ` Daniel Wagner
2015-12-18 14:13                     ` pi3orama
     [not found]                     ` <66E52D4A-BA1C-456A-8E6F-975E07C083EE@163.com>
2015-12-18 14:22                       ` Daniel Wagner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.