linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 perf/core 0/6] Libbpf object pinning
@ 2017-01-26 21:19 Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
                   ` (6 more replies)
  0 siblings, 7 replies; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:19 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

This series adds pinning functionality for maps, programs, and objects.
Library users may call bpf_map__pin(map, path) or bpf_program__pin(prog, path)
to pin maps and programs separately, or use bpf_object__pin(obj, path) to
pin all maps and programs from the BPF object to the path. The map and program
variations require a path where it will be pinned in the filesystem,
and the object variation will create named directories for each program with
instances within, and mount the maps by name under the path.

For example, with the directory '/sys/fs/bpf/foo' and a BPF object which
contains two instances of a program named 'bar', and a map named 'baz':
/sys/fs/bpf/foo/bar/0
/sys/fs/bpf/foo/bar/1
/sys/fs/bpf/foo/baz

---
v3: Split out bpf_program__pin_instance().
    Change the paths from PATH/{maps,progs}/foo to the above.
    Drop the patches that were applied.
    Add a perf test to check that pinning works.
v2: Wang Nan provided improvements to patch 1.
    Dropped patch 2 from v1.
    Added acks for acked patches.
    Split the bpf_obj__pin() to also provide map / program pinning APIs.
    Allow users to provide full filesystem path (don't autodetect/mount BPFFS).
v1: Initial post.

Joe Stringer (6):
  tools lib bpf: Add BPF program pinning APIs.
  tools lib bpf: Add bpf_map__pin()
  tools lib bpf: Add bpf_object__pin()
  tools perf util: Make rm_rf(path) argument const
  tools lib api fs: Add bpf_fs filesystem detector
  perf test: Add libbpf pinning test

 tools/lib/api/fs/fs.c  |  16 +++++
 tools/lib/api/fs/fs.h  |   1 +
 tools/lib/bpf/libbpf.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |   5 ++
 tools/perf/tests/bpf.c |  42 ++++++++++-
 tools/perf/util/util.c |   2 +-
 tools/perf/util/util.h |   2 +-
 7 files changed, 253 insertions(+), 3 deletions(-)

-- 
2.11.0

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

* [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
@ 2017-01-26 21:19 ` Joe Stringer
  2017-01-30 20:25   ` Arnaldo Carvalho de Melo
  2017-02-01 14:40   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 2/6] tools lib bpf: Add bpf_map__pin() Joe Stringer
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:19 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Add new APIs to pin a BPF program (or specific instances) to the filesystem.
The user can specify the path full path within a BPF filesystem to pin the
program.

bpf_program__pin_instance(prog, path, n) will pin the nth instance of
'prog' to the specified path.
bpf_program__pin(prog, path) will create the directory 'path' (if it
does not exist) and pin each instance within that directory. For
instance, path/0, path/1, path/2.

Signed-off-by: Joe Stringer <joe@ovn.org>
---
v3: Add per-instance pinning.
    Use path for bpf_program__pin() as directory.
v2: Don't automount BPF filesystem
    Split program, map, object pinning into separate APIs and separate
    patches.
---
 tools/lib/bpf/libbpf.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |   3 ++
 2 files changed, 115 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e6cd62b1264b..d1d7638b7c21 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
  * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
  * Copyright (C) 2015 Huawei Inc.
+ * Copyright (C) 2017 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <libgen.h>
 #include <inttypes.h>
 #include <string.h>
 #include <unistd.h>
@@ -31,7 +33,10 @@
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/bpf.h>
+#include <linux/magic.h>
 #include <linux/list.h>
+#include <linux/limits.h>
+#include <sys/vfs.h>
 #include <libelf.h>
 #include <gelf.h>
 
@@ -1237,6 +1242,113 @@ int bpf_object__load(struct bpf_object *obj)
 	return err;
 }
 
+static int check_path(const char *path)
+{
+	struct statfs st_fs;
+	char *dname, *dir;
+	int err = 0;
+
+	if (path == NULL)
+		return -EINVAL;
+
+	dname = strdup(path);
+	dir = dirname(dname);
+	if (statfs(dir, &st_fs)) {
+		pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
+		err = -errno;
+	}
+	free(dname);
+
+	if (!err && st_fs.f_type != BPF_FS_MAGIC) {
+		pr_warning("specified path %s is not on BPF FS\n", path);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
+			      int instance)
+{
+	int err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (prog == NULL) {
+		pr_warning("invalid program pointer\n");
+		return -EINVAL;
+	}
+
+	if (instance < 0 || instance >= prog->instances.nr) {
+		pr_warning("invalid prog instance %d of prog %s (max %d)\n",
+			   instance, prog->section_name, prog->instances.nr);
+		return -EINVAL;
+	}
+
+	if (bpf_obj_pin(prog->instances.fds[instance], path)) {
+		pr_warning("failed to pin program: %s\n", strerror(errno));
+		return -errno;
+	}
+	pr_debug("pinned program '%s'\n", path);
+
+	return 0;
+}
+
+static int make_dir(const char *path)
+{
+	int err = 0;
+
+	if (mkdir(path, 0700) && errno != EEXIST)
+		err = -errno;
+
+	if (err)
+		pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
+	return err;
+}
+
+int bpf_program__pin(struct bpf_program *prog, const char *path)
+{
+	int i, err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (prog == NULL) {
+		pr_warning("invalid program pointer\n");
+		return -EINVAL;
+	}
+
+	if (prog->instances.nr <= 0) {
+		pr_warning("no instances of prog %s to pin\n",
+			   prog->section_name);
+		return -EINVAL;
+	}
+
+	err = make_dir(path);
+	if (err)
+		return err;
+
+	for (i = 0; i < prog->instances.nr; i++) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
+		if (len < 0)
+			return -EINVAL;
+		else if (len > PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_program__pin_instance(prog, buf, i);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 4014d1ba5e3d..9f8aa63b95f4 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -106,6 +106,9 @@ void *bpf_program__priv(struct bpf_program *prog);
 const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
 
 int bpf_program__fd(struct bpf_program *prog);
+int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
+			      int instance);
+int bpf_program__pin(struct bpf_program *prog, const char *path);
 
 struct bpf_insn;
 
-- 
2.11.0

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

* [PATCHv3 perf/core 2/6] tools lib bpf: Add bpf_map__pin()
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
@ 2017-01-26 21:19 ` Joe Stringer
  2017-02-01 14:40   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 3/6] tools lib bpf: Add bpf_object__pin() Joe Stringer
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:19 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Add a new API to pin a BPF map to the filesystem. The user can
specify the path full path within a BPF filesystem to pin the map.

Signed-off-by: Joe Stringer <joe@ovn.org>
---
v3: No change.
v2: Don't automount BPF filesystem
    Split program, map, object pinning into separate APIs and separate
    patches.
---
 tools/lib/bpf/libbpf.c | 22 ++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index d1d7638b7c21..ce987c02363e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1349,6 +1349,28 @@ int bpf_program__pin(struct bpf_program *prog, const char *path)
 	return 0;
 }
 
+int bpf_map__pin(struct bpf_map *map, const char *path)
+{
+	int err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (map == NULL) {
+		pr_warning("invalid map pointer\n");
+		return -EINVAL;
+	}
+
+	if (bpf_obj_pin(map->fd, path)) {
+		pr_warning("failed to pin map: %s\n", strerror(errno));
+		return -errno;
+	}
+
+	pr_debug("pinned map '%s'\n", path);
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 9f8aa63b95f4..2addf9d5b13c 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -236,6 +236,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
 int bpf_map__set_priv(struct bpf_map *map, void *priv,
 		      bpf_map_clear_priv_t clear_priv);
 void *bpf_map__priv(struct bpf_map *map);
+int bpf_map__pin(struct bpf_map *map, const char *path);
 
 long libbpf_get_error(const void *ptr);
 
-- 
2.11.0

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

* [PATCHv3 perf/core 3/6] tools lib bpf: Add bpf_object__pin()
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 2/6] tools lib bpf: Add bpf_map__pin() Joe Stringer
@ 2017-01-26 21:19 ` Joe Stringer
  2017-02-01 14:41   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-26 21:19 ` [PATCHv3 perf/core 4/6] tools perf util: Make rm_rf(path) argument const Joe Stringer
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:19 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Add a new API to pin a BPF object to the filesystem. The user can
specify the path within a BPF filesystem to pin the object.
Programs will be pinned under a subdirectory named the same as the
program, with each instance appearing as a numbered file under that
directory, and maps will be pinned under the path using the name of
the map as the file basename.

For example, with the directory '/sys/fs/bpf/foo' and a BPF object which
contains two instances of a program named 'bar', and a map named 'baz':
/sys/fs/bpf/foo/bar/0
/sys/fs/bpf/foo/bar/1
/sys/fs/bpf/foo/baz

Signed-off-by: Joe Stringer <joe@ovn.org>
---
v3: Mount to PATH/MAPNAME, PATH/PROGNAME/N (N = instance number)
v2: Don't automount BPF filesystem
    Split program, map, object pinning into separate APIs and separate
    patches.
---
 tools/lib/bpf/libbpf.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 55 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ce987c02363e..703cfa986b34 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -36,6 +36,7 @@
 #include <linux/magic.h>
 #include <linux/list.h>
 #include <linux/limits.h>
+#include <sys/stat.h>
 #include <sys/vfs.h>
 #include <libelf.h>
 #include <gelf.h>
@@ -1371,6 +1372,59 @@ int bpf_map__pin(struct bpf_map *map, const char *path)
 	return 0;
 }
 
+int bpf_object__pin(struct bpf_object *obj, const char *path)
+{
+	struct bpf_program *prog;
+	struct bpf_map *map;
+	int err;
+
+	if (!obj)
+		return -ENOENT;
+
+	if (!obj->loaded) {
+		pr_warning("object not yet loaded; load it first\n");
+		return -ENOENT;
+	}
+
+	err = make_dir(path);
+	if (err)
+		return err;
+
+	bpf_map__for_each(map, obj) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%s", path,
+			       bpf_map__name(map));
+		if (len < 0)
+			return -EINVAL;
+		else if (len > PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_map__pin(map, buf);
+		if (err)
+			return err;
+	}
+
+	bpf_object__for_each_program(prog, obj) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%s", path,
+			       prog->section_name);
+		if (len < 0)
+			return -EINVAL;
+		else if (len > PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_program__pin(prog, buf);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 2addf9d5b13c..b30394f9947a 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -65,6 +65,7 @@ struct bpf_object *bpf_object__open(const char *path);
 struct bpf_object *bpf_object__open_buffer(void *obj_buf,
 					   size_t obj_buf_sz,
 					   const char *name);
+int bpf_object__pin(struct bpf_object *object, const char *path);
 void bpf_object__close(struct bpf_object *object);
 
 /* Load/unload object into/from kernel */
-- 
2.11.0

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

* [PATCHv3 perf/core 4/6] tools perf util: Make rm_rf(path) argument const
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
                   ` (2 preceding siblings ...)
  2017-01-26 21:19 ` [PATCHv3 perf/core 3/6] tools lib bpf: Add bpf_object__pin() Joe Stringer
@ 2017-01-26 21:19 ` Joe Stringer
  2017-02-01 14:41   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-26 21:20 ` [PATCHv3 perf/core 5/6] tools lib api fs: Add bpf_fs filesystem detector Joe Stringer
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:19 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

rm_rf() doesn't modify its path argument, and a future caller will pass
a string constant into it to delete.

Signed-off-by: Joe Stringer <joe@ovn.org>
---
v3: Initial post.
---
 tools/perf/util/util.c | 2 +-
 tools/perf/util/util.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index bf29aed16bd6..d8b45cea54d0 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode)
 	return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
 }
 
-int rm_rf(char *path)
+int rm_rf(const char *path)
 {
 	DIR *dir;
 	int ret = 0;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 6e8be174ec0b..c74708da8571 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -209,7 +209,7 @@ static inline int sane_case(int x, int high)
 }
 
 int mkdir_p(char *path, mode_t mode);
-int rm_rf(char *path);
+int rm_rf(const char *path);
 struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
 bool lsdir_no_dot_filter(const char *name, struct dirent *d);
 int copyfile(const char *from, const char *to);
-- 
2.11.0

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

* [PATCHv3 perf/core 5/6] tools lib api fs: Add bpf_fs filesystem detector
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
                   ` (3 preceding siblings ...)
  2017-01-26 21:19 ` [PATCHv3 perf/core 4/6] tools perf util: Make rm_rf(path) argument const Joe Stringer
@ 2017-01-26 21:20 ` Joe Stringer
  2017-02-01 14:42   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-26 21:20 ` [PATCHv3 perf/core 6/6] perf test: Add libbpf pinning test Joe Stringer
  2017-01-30 20:37 ` [PATCHv3 perf/core 0/6] Libbpf object pinning Arnaldo Carvalho de Melo
  6 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:20 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Allow mounting of the BPF filesystem at /sys/fs/bpf.

Signed-off-by: Joe Stringer <joe@ovn.org>
---
v3: Initial post.
---
 tools/lib/api/fs/fs.c | 16 ++++++++++++++++
 tools/lib/api/fs/fs.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index f99f49e4a31e..4b6bfc43cccf 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -38,6 +38,10 @@
 #define HUGETLBFS_MAGIC        0x958458f6
 #endif
 
+#ifndef BPF_FS_MAGIC
+#define BPF_FS_MAGIC           0xcafe4a11
+#endif
+
 static const char * const sysfs__fs_known_mountpoints[] = {
 	"/sys",
 	0,
@@ -75,6 +79,11 @@ static const char * const hugetlbfs__known_mountpoints[] = {
 	0,
 };
 
+static const char * const bpf_fs__known_mountpoints[] = {
+	"/sys/fs/bpf",
+	0,
+};
+
 struct fs {
 	const char		*name;
 	const char * const	*mounts;
@@ -89,6 +98,7 @@ enum {
 	FS__DEBUGFS = 2,
 	FS__TRACEFS = 3,
 	FS__HUGETLBFS = 4,
+	FS__BPF_FS = 5,
 };
 
 #ifndef TRACEFS_MAGIC
@@ -121,6 +131,11 @@ static struct fs fs__entries[] = {
 		.mounts = hugetlbfs__known_mountpoints,
 		.magic	= HUGETLBFS_MAGIC,
 	},
+	[FS__BPF_FS] = {
+		.name	= "bpf",
+		.mounts = bpf_fs__known_mountpoints,
+		.magic	= BPF_FS_MAGIC,
+	},
 };
 
 static bool fs__read_mounts(struct fs *fs)
@@ -280,6 +295,7 @@ FS(procfs,  FS__PROCFS);
 FS(debugfs, FS__DEBUGFS);
 FS(tracefs, FS__TRACEFS);
 FS(hugetlbfs, FS__HUGETLBFS);
+FS(bpf_fs, FS__BPF_FS);
 
 int filename__read_int(const char *filename, int *value)
 {
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index a63269f5d20c..6b332dc74498 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -22,6 +22,7 @@ FS(procfs)
 FS(debugfs)
 FS(tracefs)
 FS(hugetlbfs)
+FS(bpf_fs)
 
 #undef FS
 
-- 
2.11.0

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

* [PATCHv3 perf/core 6/6] perf test: Add libbpf pinning test
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
                   ` (4 preceding siblings ...)
  2017-01-26 21:20 ` [PATCHv3 perf/core 5/6] tools lib api fs: Add bpf_fs filesystem detector Joe Stringer
@ 2017-01-26 21:20 ` Joe Stringer
  2017-02-01 14:42   ` [tip:perf/core] " tip-bot for Joe Stringer
  2017-01-30 20:37 ` [PATCHv3 perf/core 0/6] Libbpf object pinning Arnaldo Carvalho de Melo
  6 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-26 21:20 UTC (permalink / raw)
  To: acme; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Add a test for the newly added BPF object pinning functionality.

For example:
  # tools/perf/perf test 37
    37: BPF filter                                 :
    37.1: Basic BPF filtering                      : Ok
    37.2: BPF pinning                              : Ok
    37.3: BPF prologue generation                  : Ok
    37.4: BPF relocation checker                   : Ok

  # tools/perf/perf test 37 -v 2>&1 | grep pinned
    libbpf: pinned map '/sys/fs/bpf/perf_test/flip_table'
    libbpf: pinned program '/sys/fs/bpf/perf_test/func=SyS_epoll_wait/0'

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
---
v3: Initial post.
---
 tools/perf/tests/bpf.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 92343f43e44a..1a04fe77487d 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -5,11 +5,13 @@
 #include <util/evlist.h>
 #include <linux/bpf.h>
 #include <linux/filter.h>
+#include <api/fs/fs.h>
 #include <bpf/bpf.h>
 #include "tests.h"
 #include "llvm.h"
 #include "debug.h"
 #define NR_ITERS       111
+#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
 
 #ifdef HAVE_LIBBPF_SUPPORT
 
@@ -54,6 +56,7 @@ static struct {
 	const char *msg_load_fail;
 	int (*target_func)(void);
 	int expect_result;
+	bool	pin;
 } bpf_testcase_table[] = {
 	{
 		LLVM_TESTCASE_BASE,
@@ -63,6 +66,17 @@ static struct {
 		"load bpf object failed",
 		&epoll_wait_loop,
 		(NR_ITERS + 1) / 2,
+		false,
+	},
+	{
+		LLVM_TESTCASE_BASE,
+		"BPF pinning",
+		"[bpf_pinning]",
+		"fix kbuild first",
+		"check your vmlinux setting?",
+		&epoll_wait_loop,
+		(NR_ITERS + 1) / 2,
+		true,
 	},
 #ifdef HAVE_BPF_PROLOGUE
 	{
@@ -73,6 +87,7 @@ static struct {
 		"check your vmlinux setting?",
 		&llseek_loop,
 		(NR_ITERS + 1) / 4,
+		false,
 	},
 #endif
 	{
@@ -83,6 +98,7 @@ static struct {
 		"libbpf error when dealing with relocation",
 		NULL,
 		0,
+		false,
 	},
 };
 
@@ -226,10 +242,34 @@ static int __test__bpf(int idx)
 		goto out;
 	}
 
-	if (obj)
+	if (obj) {
 		ret = do_test(obj,
 			      bpf_testcase_table[idx].target_func,
 			      bpf_testcase_table[idx].expect_result);
+		if (ret != TEST_OK)
+			goto out;
+		if (bpf_testcase_table[idx].pin) {
+			int err;
+
+			if (!bpf_fs__mount()) {
+				pr_debug("BPF filesystem not mounted\n");
+				ret = TEST_FAIL;
+				goto out;
+			}
+			err = mkdir(PERF_TEST_BPF_PATH, 0777);
+			if (err && errno != EEXIST) {
+				pr_debug("Failed to make perf_test dir: %s\n",
+					 strerror(errno));
+				ret = TEST_FAIL;
+				goto out;
+			}
+			if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
+				ret = TEST_FAIL;
+			if (rm_rf(PERF_TEST_BPF_PATH))
+				ret = TEST_FAIL;
+		}
+	}
+
 out:
 	bpf__clear();
 	return ret;
-- 
2.11.0

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
@ 2017-01-30 20:25   ` Arnaldo Carvalho de Melo
  2017-01-30 20:28     ` Arnaldo Carvalho de Melo
  2017-02-01 14:40   ` [tip:perf/core] " tip-bot for Joe Stringer
  1 sibling, 1 reply; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-30 20:25 UTC (permalink / raw)
  To: Joe Stringer; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Em Thu, Jan 26, 2017 at 01:19:56PM -0800, Joe Stringer escreveu:
> Add new APIs to pin a BPF program (or specific instances) to the filesystem.
> The user can specify the path full path within a BPF filesystem to pin the
> program.
> 
> bpf_program__pin_instance(prog, path, n) will pin the nth instance of
> 'prog' to the specified path.
> bpf_program__pin(prog, path) will create the directory 'path' (if it
> does not exist) and pin each instance within that directory. For
> instance, path/0, path/1, path/2.
> 
> Signed-off-by: Joe Stringer <joe@ovn.org>

make: Entering directory '/home/acme/git/linux/tools/perf'
  BUILD:   Doing 'make -j4' parallel build
  CC       /tmp/build/perf/builtin-record.o
  CC       /tmp/build/perf/libbpf.o
  CC       /tmp/build/perf/util/parse-events.o
  INSTALL  trace_plugins
libbpf.c: In function ‘make_dir’:
libbpf.c:1303:6: error: implicit declaration of function ‘mkdir’ [-Werror=implicit-function-declaration]
  if (mkdir(path, 0700) && errno != EEXIST)
      ^~~~~
libbpf.c:1303:2: error: nested extern declaration of ‘mkdir’ [-Werror=nested-externs]
  if (mkdir(path, 0700) && errno != EEXIST)
  ^~
cc1: all warnings being treated as errors
mv: cannot stat '/tmp/build/perf/.libbpf.o.tmp': No such file or directory
/home/acme/git/linux/tools/build/Makefile.build:101: recipe for target '/tmp/build/perf/libbpf.o' failed


And strdup() is not checked for failure, I'm fixing those,

+++ b/tools/lib/bpf/libbpf.c
@@ -36,6 +36,8 @@
 #include <linux/magic.h>
 #include <linux/list.h>
 #include <linux/limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <sys/vfs.h>


- Arnaldo

> ---
> v3: Add per-instance pinning.
>     Use path for bpf_program__pin() as directory.
> v2: Don't automount BPF filesystem
>     Split program, map, object pinning into separate APIs and separate
>     patches.
> ---
>  tools/lib/bpf/libbpf.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.h |   3 ++
>  2 files changed, 115 insertions(+)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index e6cd62b1264b..d1d7638b7c21 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -4,6 +4,7 @@
>   * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
>   * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
>   * Copyright (C) 2015 Huawei Inc.
> + * Copyright (C) 2017 Nicira, Inc.
>   *
>   * This program is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU Lesser General Public
> @@ -22,6 +23,7 @@
>  #include <stdlib.h>
>  #include <stdio.h>
>  #include <stdarg.h>
> +#include <libgen.h>
>  #include <inttypes.h>
>  #include <string.h>
>  #include <unistd.h>
> @@ -31,7 +33,10 @@
>  #include <linux/err.h>
>  #include <linux/kernel.h>
>  #include <linux/bpf.h>
> +#include <linux/magic.h>
>  #include <linux/list.h>
> +#include <linux/limits.h>
> +#include <sys/vfs.h>
>  #include <libelf.h>
>  #include <gelf.h>
>  
> @@ -1237,6 +1242,113 @@ int bpf_object__load(struct bpf_object *obj)
>  	return err;
>  }
>  
> +static int check_path(const char *path)
> +{
> +	struct statfs st_fs;
> +	char *dname, *dir;
> +	int err = 0;
> +
> +	if (path == NULL)
> +		return -EINVAL;
> +
> +	dname = strdup(path);
> +	dir = dirname(dname);
> +	if (statfs(dir, &st_fs)) {
> +		pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
> +		err = -errno;
> +	}
> +	free(dname);
> +
> +	if (!err && st_fs.f_type != BPF_FS_MAGIC) {
> +		pr_warning("specified path %s is not on BPF FS\n", path);
> +		err = -EINVAL;
> +	}
> +
> +	return err;
> +}
> +
> +int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
> +			      int instance)
> +{
> +	int err;
> +
> +	err = check_path(path);
> +	if (err)
> +		return err;
> +
> +	if (prog == NULL) {
> +		pr_warning("invalid program pointer\n");
> +		return -EINVAL;
> +	}
> +
> +	if (instance < 0 || instance >= prog->instances.nr) {
> +		pr_warning("invalid prog instance %d of prog %s (max %d)\n",
> +			   instance, prog->section_name, prog->instances.nr);
> +		return -EINVAL;
> +	}
> +
> +	if (bpf_obj_pin(prog->instances.fds[instance], path)) {
> +		pr_warning("failed to pin program: %s\n", strerror(errno));
> +		return -errno;
> +	}
> +	pr_debug("pinned program '%s'\n", path);
> +
> +	return 0;
> +}
> +
> +static int make_dir(const char *path)
> +{
> +	int err = 0;
> +
> +	if (mkdir(path, 0700) && errno != EEXIST)
> +		err = -errno;
> +
> +	if (err)
> +		pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
> +	return err;
> +}
> +
> +int bpf_program__pin(struct bpf_program *prog, const char *path)
> +{
> +	int i, err;
> +
> +	err = check_path(path);
> +	if (err)
> +		return err;
> +
> +	if (prog == NULL) {
> +		pr_warning("invalid program pointer\n");
> +		return -EINVAL;
> +	}
> +
> +	if (prog->instances.nr <= 0) {
> +		pr_warning("no instances of prog %s to pin\n",
> +			   prog->section_name);
> +		return -EINVAL;
> +	}
> +
> +	err = make_dir(path);
> +	if (err)
> +		return err;
> +
> +	for (i = 0; i < prog->instances.nr; i++) {
> +		char buf[PATH_MAX];
> +		int len;
> +
> +		len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
> +		if (len < 0)
> +			return -EINVAL;
> +		else if (len > PATH_MAX)
> +			return -ENAMETOOLONG;
> +
> +		err = bpf_program__pin_instance(prog, buf, i);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
>  void bpf_object__close(struct bpf_object *obj)
>  {
>  	size_t i;
> diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
> index 4014d1ba5e3d..9f8aa63b95f4 100644
> --- a/tools/lib/bpf/libbpf.h
> +++ b/tools/lib/bpf/libbpf.h
> @@ -106,6 +106,9 @@ void *bpf_program__priv(struct bpf_program *prog);
>  const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
>  
>  int bpf_program__fd(struct bpf_program *prog);
> +int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
> +			      int instance);
> +int bpf_program__pin(struct bpf_program *prog, const char *path);
>  
>  struct bpf_insn;
>  
> -- 
> 2.11.0

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-30 20:25   ` Arnaldo Carvalho de Melo
@ 2017-01-30 20:28     ` Arnaldo Carvalho de Melo
  2017-01-30 21:16       ` Joe Stringer
  0 siblings, 1 reply; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-30 20:28 UTC (permalink / raw)
  To: Joe Stringer; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Em Mon, Jan 30, 2017 at 05:25:06PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Jan 26, 2017 at 01:19:56PM -0800, Joe Stringer escreveu:
> > Add new APIs to pin a BPF program (or specific instances) to the filesystem.
> > The user can specify the path full path within a BPF filesystem to pin the
> > program.
> > 
> > bpf_program__pin_instance(prog, path, n) will pin the nth instance of
> > 'prog' to the specified path.
> > bpf_program__pin(prog, path) will create the directory 'path' (if it
> > does not exist) and pin each instance within that directory. For
> > instance, path/0, path/1, path/2.
> > 
> > Signed-off-by: Joe Stringer <joe@ovn.org>
> 
> make: Entering directory '/home/acme/git/linux/tools/perf'
>   BUILD:   Doing 'make -j4' parallel build
>   CC       /tmp/build/perf/builtin-record.o
>   CC       /tmp/build/perf/libbpf.o
>   CC       /tmp/build/perf/util/parse-events.o
>   INSTALL  trace_plugins
> libbpf.c: In function ‘make_dir’:
> libbpf.c:1303:6: error: implicit declaration of function ‘mkdir’ [-Werror=implicit-function-declaration]
>   if (mkdir(path, 0700) && errno != EEXIST)
>       ^~~~~
> libbpf.c:1303:2: error: nested extern declaration of ‘mkdir’ [-Werror=nested-externs]
>   if (mkdir(path, 0700) && errno != EEXIST)
>   ^~
> cc1: all warnings being treated as errors
> mv: cannot stat '/tmp/build/perf/.libbpf.o.tmp': No such file or directory
> /home/acme/git/linux/tools/build/Makefile.build:101: recipe for target '/tmp/build/perf/libbpf.o' failed
> 
> 
> And strdup() is not checked for failure, I'm fixing those,
> 
> +++ b/tools/lib/bpf/libbpf.c
> @@ -36,6 +36,8 @@
>  #include <linux/magic.h>
>  #include <linux/list.h>
>  #include <linux/limits.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
>  #include <sys/vfs.h>

This as well:

@@ -1338,7 +1343,7 @@ int bpf_program__pin(struct bpf_program *prog,
const char *path)
                len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
                if (len < 0)
                        return -EINVAL;
-               else if (len > PATH_MAX)
+               else if (len >= PATH_MAX)
                        return -ENAMETOOLONG;


See 'man snprintf', return value:

---
Thus, a return value of size or more means that the output was
truncated.
---

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

* Re: [PATCHv3 perf/core 0/6] Libbpf object pinning
  2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
                   ` (5 preceding siblings ...)
  2017-01-26 21:20 ` [PATCHv3 perf/core 6/6] perf test: Add libbpf pinning test Joe Stringer
@ 2017-01-30 20:37 ` Arnaldo Carvalho de Melo
  6 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-30 20:37 UTC (permalink / raw)
  To: Joe Stringer; +Cc: wangnan0, ast, daniel, linux-kernel, netdev

Em Thu, Jan 26, 2017 at 01:19:55PM -0800, Joe Stringer escreveu:
> This series adds pinning functionality for maps, programs, and objects.
> Library users may call bpf_map__pin(map, path) or bpf_program__pin(prog, path)
> to pin maps and programs separately, or use bpf_object__pin(obj, path) to
> pin all maps and programs from the BPF object to the path. The map and program
> variations require a path where it will be pinned in the filesystem,
> and the object variation will create named directories for each program with
> instances within, and mount the maps by name under the path.
> 
> For example, with the directory '/sys/fs/bpf/foo' and a BPF object which
> contains two instances of a program named 'bar', and a map named 'baz':
> /sys/fs/bpf/foo/bar/0
> /sys/fs/bpf/foo/bar/1
> /sys/fs/bpf/foo/baz

Thanks, applied, after some minor fixes.

- Arnaldo
 
> ---
> v3: Split out bpf_program__pin_instance().
>     Change the paths from PATH/{maps,progs}/foo to the above.
>     Drop the patches that were applied.
>     Add a perf test to check that pinning works.
> v2: Wang Nan provided improvements to patch 1.
>     Dropped patch 2 from v1.
>     Added acks for acked patches.
>     Split the bpf_obj__pin() to also provide map / program pinning APIs.
>     Allow users to provide full filesystem path (don't autodetect/mount BPFFS).
> v1: Initial post.
> 
> Joe Stringer (6):
>   tools lib bpf: Add BPF program pinning APIs.
>   tools lib bpf: Add bpf_map__pin()
>   tools lib bpf: Add bpf_object__pin()
>   tools perf util: Make rm_rf(path) argument const
>   tools lib api fs: Add bpf_fs filesystem detector
>   perf test: Add libbpf pinning test
> 
>  tools/lib/api/fs/fs.c  |  16 +++++
>  tools/lib/api/fs/fs.h  |   1 +
>  tools/lib/bpf/libbpf.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++++
>  tools/lib/bpf/libbpf.h |   5 ++
>  tools/perf/tests/bpf.c |  42 ++++++++++-
>  tools/perf/util/util.c |   2 +-
>  tools/perf/util/util.h |   2 +-
>  7 files changed, 253 insertions(+), 3 deletions(-)
> 
> -- 
> 2.11.0

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-30 20:28     ` Arnaldo Carvalho de Melo
@ 2017-01-30 21:16       ` Joe Stringer
  2017-01-31  0:58         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 21+ messages in thread
From: Joe Stringer @ 2017-01-30 21:16 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: Wang Nan, ast, Daniel Borkmann, LKML, netdev

On 30 January 2017 at 12:28, Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> Em Mon, Jan 30, 2017 at 05:25:06PM -0300, Arnaldo Carvalho de Melo escreveu:
>> Em Thu, Jan 26, 2017 at 01:19:56PM -0800, Joe Stringer escreveu:
>> > Add new APIs to pin a BPF program (or specific instances) to the filesystem.
>> > The user can specify the path full path within a BPF filesystem to pin the
>> > program.
>> >
>> > bpf_program__pin_instance(prog, path, n) will pin the nth instance of
>> > 'prog' to the specified path.
>> > bpf_program__pin(prog, path) will create the directory 'path' (if it
>> > does not exist) and pin each instance within that directory. For
>> > instance, path/0, path/1, path/2.
>> >
>> > Signed-off-by: Joe Stringer <joe@ovn.org>
>>
>> make: Entering directory '/home/acme/git/linux/tools/perf'
>>   BUILD:   Doing 'make -j4' parallel build
>>   CC       /tmp/build/perf/builtin-record.o
>>   CC       /tmp/build/perf/libbpf.o
>>   CC       /tmp/build/perf/util/parse-events.o
>>   INSTALL  trace_plugins
>> libbpf.c: In function ‘make_dir’:
>> libbpf.c:1303:6: error: implicit declaration of function ‘mkdir’ [-Werror=implicit-function-declaration]
>>   if (mkdir(path, 0700) && errno != EEXIST)
>>       ^~~~~
>> libbpf.c:1303:2: error: nested extern declaration of ‘mkdir’ [-Werror=nested-externs]
>>   if (mkdir(path, 0700) && errno != EEXIST)
>>   ^~
>> cc1: all warnings being treated as errors
>> mv: cannot stat '/tmp/build/perf/.libbpf.o.tmp': No such file or directory
>> /home/acme/git/linux/tools/build/Makefile.build:101: recipe for target '/tmp/build/perf/libbpf.o' failed

Not sure why but I didn't see this. Appreciate the fix.

>>
>>
>> And strdup() is not checked for failure, I'm fixing those,
>>
>> +++ b/tools/lib/bpf/libbpf.c
>> @@ -36,6 +36,8 @@
>>  #include <linux/magic.h>
>>  #include <linux/list.h>
>>  #include <linux/limits.h>
>> +#include <sys/stat.h>
>> +#include <sys/types.h>
>>  #include <sys/vfs.h>
>
> This as well:
>
> @@ -1338,7 +1343,7 @@ int bpf_program__pin(struct bpf_program *prog,
> const char *path)
>                 len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
>                 if (len < 0)
>                         return -EINVAL;
> -               else if (len > PATH_MAX)
> +               else if (len >= PATH_MAX)
>                         return -ENAMETOOLONG;
>
>
> See 'man snprintf', return value:
>
> ---
> Thus, a return value of size or more means that the output was
> truncated.
> ---

Good spotting, I looked over the committed versions and tested them,
they seem good to me. Thanks!

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-30 21:16       ` Joe Stringer
@ 2017-01-31  0:58         ` Arnaldo Carvalho de Melo
  2017-01-31 16:08           ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-31  0:58 UTC (permalink / raw)
  To: Joe Stringer; +Cc: Wang Nan, ast, Daniel Borkmann, LKML, netdev

Em Mon, Jan 30, 2017 at 01:16:18PM -0800, Joe Stringer escreveu:
> On 30 January 2017 at 12:28, Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> > ---
> > Thus, a return value of size or more means that the output was
> > truncated.
> > ---
 
> Good spotting, I looked over the committed versions and tested them,
> they seem good to me. Thanks!

Thanks for checking, will push Ingo's way after a battery of extra
tests, tomorrow,

- Arnaldo

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-31  0:58         ` Arnaldo Carvalho de Melo
@ 2017-01-31 16:08           ` Arnaldo Carvalho de Melo
  2017-01-31 16:13             ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-31 16:08 UTC (permalink / raw)
  To: Joe Stringer; +Cc: Wang Nan, ast, Daniel Borkmann, LKML, netdev

Em Mon, Jan 30, 2017 at 09:58:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 30, 2017 at 01:16:18PM -0800, Joe Stringer escreveu:
> > On 30 January 2017 at 12:28, Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> > > ---
> > > Thus, a return value of size or more means that the output was
> > > truncated.
> > > ---
>  
> > Good spotting, I looked over the committed versions and tested them,
> > they seem good to me. Thanks!
> 
> Thanks for checking, will push Ingo's way after a battery of extra
> tests, tomorrow,

Which failed for centos:5, centos:6, centos:7, debian:7, debian:8,
debian:experimental and others, I stopped the test at this point,
working on fixing it.

All seems related to:

libbpf.c:1267: error: 'BPF_FS_MAGIC' undeclared (first use in this function)
libbpf.c:1267: error: (Each undeclared identifier is reported only once
libbpf.c:1267: error: for each function it appears in.)

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-31 16:08           ` Arnaldo Carvalho de Melo
@ 2017-01-31 16:13             ` Arnaldo Carvalho de Melo
  2017-01-31 16:42               ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-31 16:13 UTC (permalink / raw)
  To: Joe Stringer; +Cc: Wang Nan, ast, Daniel Borkmann, LKML, netdev

Em Tue, Jan 31, 2017 at 01:08:27PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 30, 2017 at 09:58:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 30, 2017 at 01:16:18PM -0800, Joe Stringer escreveu:
> > > On 30 January 2017 at 12:28, Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> > > > ---
> > > > Thus, a return value of size or more means that the output was
> > > > truncated.
> > > > ---
> >  
> > > Good spotting, I looked over the committed versions and tested them,
> > > they seem good to me. Thanks!
> > 
> > Thanks for checking, will push Ingo's way after a battery of extra
> > tests, tomorrow,
> 
> Which failed for centos:5, centos:6, centos:7, debian:7, debian:8,
> debian:experimental and others, I stopped the test at this point,
> working on fixing it.
> 
> All seems related to:
> 
> libbpf.c:1267: error: 'BPF_FS_MAGIC' undeclared (first use in this function)
> libbpf.c:1267: error: (Each undeclared identifier is reported only once
> libbpf.c:1267: error: for each function it appears in.)

We need to carry a tools/include/uapi/linux/magic.c copy, check if it
drifts, remove the ifdefs for _FS_MAGIC defines from tools/ and use that
instead, etc, till then I'll just add the ifdef to libbpf.c.

[acme@jouet linux]$ grep BPF_FS_MAGIC /usr/include/*/*.h
/usr/include/linux/magic.h:#define BPF_FS_MAGIC		0xcafe4a11
[acme@jouet linux]$ rpm -qf /usr/include/linux/magic.h
kernel-headers-4.9.6-200.fc25.x86_64
[acme@jouet linux]$ cat /etc/fedora-release 
Fedora release 25 (Twenty Five)
[acme@jouet linux]$ 

But those other distros don't have it.

- Arnaldo

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

* Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
  2017-01-31 16:13             ` Arnaldo Carvalho de Melo
@ 2017-01-31 16:42               ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2017-01-31 16:42 UTC (permalink / raw)
  To: Joe Stringer; +Cc: Wang Nan, ast, Daniel Borkmann, LKML, netdev

Em Tue, Jan 31, 2017 at 01:13:20PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 31, 2017 at 01:08:27PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 30, 2017 at 09:58:05PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Jan 30, 2017 at 01:16:18PM -0800, Joe Stringer escreveu:
> > > > On 30 January 2017 at 12:28, Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> > > > > ---
> > > > > Thus, a return value of size or more means that the output was
> > > > > truncated.
> > > > > ---
> > >  
> > > > Good spotting, I looked over the committed versions and tested them,
> > > > they seem good to me. Thanks!
> > > 
> > > Thanks for checking, will push Ingo's way after a battery of extra
> > > tests, tomorrow,
> > 
> > Which failed for centos:5, centos:6, centos:7, debian:7, debian:8,
> > debian:experimental and others, I stopped the test at this point,
> > working on fixing it.
> > 
> > All seems related to:
> > 
> > libbpf.c:1267: error: 'BPF_FS_MAGIC' undeclared (first use in this function)
> > libbpf.c:1267: error: (Each undeclared identifier is reported only once
> > libbpf.c:1267: error: for each function it appears in.)
> 
> We need to carry a tools/include/uapi/linux/magic.c copy, check if it
> drifts, remove the ifdefs for _FS_MAGIC defines from tools/ and use that
> instead, etc, till then I'll just add the ifdef to libbpf.c.

After also removing that

#include <linux/magic.h>

line, that is not used anywhere else in tools/{perf,include,lib}/ it is
going further:

[root@jouet ~]# time dm
   1 83.120412349 alpine:3.4: Ok
   2 35.486456929 android-ndk:r12b-arm: Ok
   3 85.384259996 archlinux:latest: Ok
   4 49.518031326 centos:5: Ok
   5 70.417375831 centos:6: Ok
   6 87.033156092 centos:7: Ok

31 more to go

:-)

- Arnaldo

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

* [tip:perf/core] tools lib bpf: Add BPF program pinning APIs
  2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
  2017-01-30 20:25   ` Arnaldo Carvalho de Melo
@ 2017-02-01 14:40   ` tip-bot for Joe Stringer
  1 sibling, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:40 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: wangnan0, linux-kernel, ast, tglx, mingo, acme, joe, daniel, hpa

Commit-ID:  f367540c8c13d65603c431e29a0b87a7db893d6c
Gitweb:     http://git.kernel.org/tip/f367540c8c13d65603c431e29a0b87a7db893d6c
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:19:56 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:05 -0300

tools lib bpf: Add BPF program pinning APIs

Add new APIs to pin a BPF program (or specific instances) to the
filesystem.  The user can specify the path full path within a BPF
filesystem to pin the program.

bpf_program__pin_instance(prog, path, n) will pin the nth instance of
'prog' to the specified path.

bpf_program__pin(prog, path) will create the directory 'path' (if it
does not exist) and pin each instance within that directory. For
instance, path/0, path/1, path/2.

Committer notes:

- Add missing headers for mkdir()

- Check strdup() for failure

- Check snprintf >= size, not >, as == also means truncated, see 'man
  snprintf', return value.

- Conditionally define BPF_FS_MAGIC, as it isn't in magic.h in older
  systems and we're not yet having a tools/include/uapi/linux/magic.h
  copy.

- Do not include linux/magic.h, not present in older distros.

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-2-joe@ovn.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |   3 ++
 2 files changed, 123 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e6cd62b..c4465b2fd 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
  * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
  * Copyright (C) 2015 Huawei Inc.
+ * Copyright (C) 2017 Nicira, Inc.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <libgen.h>
 #include <inttypes.h>
 #include <string.h>
 #include <unistd.h>
@@ -32,6 +34,10 @@
 #include <linux/kernel.h>
 #include <linux/bpf.h>
 #include <linux/list.h>
+#include <linux/limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
 #include <libelf.h>
 #include <gelf.h>
 
@@ -42,6 +48,10 @@
 #define EM_BPF 247
 #endif
 
+#ifndef BPF_FS_MAGIC
+#define BPF_FS_MAGIC		0xcafe4a11
+#endif
+
 #define __printf(a, b)	__attribute__((format(printf, a, b)))
 
 __printf(1, 2)
@@ -1237,6 +1247,116 @@ out:
 	return err;
 }
 
+static int check_path(const char *path)
+{
+	struct statfs st_fs;
+	char *dname, *dir;
+	int err = 0;
+
+	if (path == NULL)
+		return -EINVAL;
+
+	dname = strdup(path);
+	if (dname == NULL)
+		return -ENOMEM;
+
+	dir = dirname(dname);
+	if (statfs(dir, &st_fs)) {
+		pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
+		err = -errno;
+	}
+	free(dname);
+
+	if (!err && st_fs.f_type != BPF_FS_MAGIC) {
+		pr_warning("specified path %s is not on BPF FS\n", path);
+		err = -EINVAL;
+	}
+
+	return err;
+}
+
+int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
+			      int instance)
+{
+	int err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (prog == NULL) {
+		pr_warning("invalid program pointer\n");
+		return -EINVAL;
+	}
+
+	if (instance < 0 || instance >= prog->instances.nr) {
+		pr_warning("invalid prog instance %d of prog %s (max %d)\n",
+			   instance, prog->section_name, prog->instances.nr);
+		return -EINVAL;
+	}
+
+	if (bpf_obj_pin(prog->instances.fds[instance], path)) {
+		pr_warning("failed to pin program: %s\n", strerror(errno));
+		return -errno;
+	}
+	pr_debug("pinned program '%s'\n", path);
+
+	return 0;
+}
+
+static int make_dir(const char *path)
+{
+	int err = 0;
+
+	if (mkdir(path, 0700) && errno != EEXIST)
+		err = -errno;
+
+	if (err)
+		pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
+	return err;
+}
+
+int bpf_program__pin(struct bpf_program *prog, const char *path)
+{
+	int i, err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (prog == NULL) {
+		pr_warning("invalid program pointer\n");
+		return -EINVAL;
+	}
+
+	if (prog->instances.nr <= 0) {
+		pr_warning("no instances of prog %s to pin\n",
+			   prog->section_name);
+		return -EINVAL;
+	}
+
+	err = make_dir(path);
+	if (err)
+		return err;
+
+	for (i = 0; i < prog->instances.nr; i++) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%d", path, i);
+		if (len < 0)
+			return -EINVAL;
+		else if (len >= PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_program__pin_instance(prog, buf, i);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 4014d1b..9f8aa63 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -106,6 +106,9 @@ void *bpf_program__priv(struct bpf_program *prog);
 const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
 
 int bpf_program__fd(struct bpf_program *prog);
+int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
+			      int instance);
+int bpf_program__pin(struct bpf_program *prog, const char *path);
 
 struct bpf_insn;
 

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

* [tip:perf/core] tools lib bpf: Add bpf_map__pin()
  2017-01-26 21:19 ` [PATCHv3 perf/core 2/6] tools lib bpf: Add bpf_map__pin() Joe Stringer
@ 2017-02-01 14:40   ` tip-bot for Joe Stringer
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:40 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: wangnan0, ast, linux-kernel, hpa, daniel, tglx, acme, joe, mingo

Commit-ID:  b6989f35e80bf830f8dc97b74128d619faef0273
Gitweb:     http://git.kernel.org/tip/b6989f35e80bf830f8dc97b74128d619faef0273
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:19:57 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:06 -0300

tools lib bpf: Add bpf_map__pin()

Add a new API to pin a BPF map to the filesystem. The user can specify
the path full path within a BPF filesystem to pin the map.

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-3-joe@ovn.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 22 ++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index c4465b2fd..6a8c8bee 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1357,6 +1357,28 @@ int bpf_program__pin(struct bpf_program *prog, const char *path)
 	return 0;
 }
 
+int bpf_map__pin(struct bpf_map *map, const char *path)
+{
+	int err;
+
+	err = check_path(path);
+	if (err)
+		return err;
+
+	if (map == NULL) {
+		pr_warning("invalid map pointer\n");
+		return -EINVAL;
+	}
+
+	if (bpf_obj_pin(map->fd, path)) {
+		pr_warning("failed to pin map: %s\n", strerror(errno));
+		return -errno;
+	}
+
+	pr_debug("pinned map '%s'\n", path);
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 9f8aa63..2addf9d 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -236,6 +236,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
 int bpf_map__set_priv(struct bpf_map *map, void *priv,
 		      bpf_map_clear_priv_t clear_priv);
 void *bpf_map__priv(struct bpf_map *map);
+int bpf_map__pin(struct bpf_map *map, const char *path);
 
 long libbpf_get_error(const void *ptr);
 

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

* [tip:perf/core] tools lib bpf: Add bpf_object__pin()
  2017-01-26 21:19 ` [PATCHv3 perf/core 3/6] tools lib bpf: Add bpf_object__pin() Joe Stringer
@ 2017-02-01 14:41   ` tip-bot for Joe Stringer
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: joe, linux-kernel, ast, tglx, hpa, wangnan0, acme, daniel, mingo

Commit-ID:  d5148d8554d08f03b3e34ecc286ab1729c35c24c
Gitweb:     http://git.kernel.org/tip/d5148d8554d08f03b3e34ecc286ab1729c35c24c
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:19:58 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:06 -0300

tools lib bpf: Add bpf_object__pin()

Add a new API to pin a BPF object to the filesystem. The user can
specify the path within a BPF filesystem to pin the object.
Programs will be pinned under a subdirectory named the same as the
program, with each instance appearing as a numbered file under that
directory, and maps will be pinned under the path using the name of
the map as the file basename.

For example, with the directory '/sys/fs/bpf/foo' and a BPF object which
contains two instances of a program named 'bar', and a map named 'baz':

/sys/fs/bpf/foo/bar/0
/sys/fs/bpf/foo/bar/1
/sys/fs/bpf/foo/baz

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-4-joe@ovn.org
[ Check snprintf >= for truncation, as snprintf(bf, size, ...) == size also means truncation ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.h |  1 +
 2 files changed, 54 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 6a8c8bee..ac6eb86 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1379,6 +1379,59 @@ int bpf_map__pin(struct bpf_map *map, const char *path)
 	return 0;
 }
 
+int bpf_object__pin(struct bpf_object *obj, const char *path)
+{
+	struct bpf_program *prog;
+	struct bpf_map *map;
+	int err;
+
+	if (!obj)
+		return -ENOENT;
+
+	if (!obj->loaded) {
+		pr_warning("object not yet loaded; load it first\n");
+		return -ENOENT;
+	}
+
+	err = make_dir(path);
+	if (err)
+		return err;
+
+	bpf_map__for_each(map, obj) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%s", path,
+			       bpf_map__name(map));
+		if (len < 0)
+			return -EINVAL;
+		else if (len >= PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_map__pin(map, buf);
+		if (err)
+			return err;
+	}
+
+	bpf_object__for_each_program(prog, obj) {
+		char buf[PATH_MAX];
+		int len;
+
+		len = snprintf(buf, PATH_MAX, "%s/%s", path,
+			       prog->section_name);
+		if (len < 0)
+			return -EINVAL;
+		else if (len >= PATH_MAX)
+			return -ENAMETOOLONG;
+
+		err = bpf_program__pin(prog, buf);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 void bpf_object__close(struct bpf_object *obj)
 {
 	size_t i;
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 2addf9d..b30394f 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -65,6 +65,7 @@ struct bpf_object *bpf_object__open(const char *path);
 struct bpf_object *bpf_object__open_buffer(void *obj_buf,
 					   size_t obj_buf_sz,
 					   const char *name);
+int bpf_object__pin(struct bpf_object *object, const char *path);
 void bpf_object__close(struct bpf_object *object);
 
 /* Load/unload object into/from kernel */

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

* [tip:perf/core] tools perf util: Make rm_rf(path) argument const
  2017-01-26 21:19 ` [PATCHv3 perf/core 4/6] tools perf util: Make rm_rf(path) argument const Joe Stringer
@ 2017-02-01 14:41   ` tip-bot for Joe Stringer
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:41 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ast, daniel, tglx, joe, hpa, mingo, acme, wangnan0, linux-kernel

Commit-ID:  9a9c733d68c5cb89bd5c5ab91b9821e1a5d69272
Gitweb:     http://git.kernel.org/tip/9a9c733d68c5cb89bd5c5ab91b9821e1a5d69272
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:19:59 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:07 -0300

tools perf util: Make rm_rf(path) argument const

rm_rf() doesn't modify its path argument, and a future caller will pass
a string constant into it to delete.

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-5-joe@ovn.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/util.c | 2 +-
 tools/perf/util/util.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index bf29aed..d8b45ce 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -85,7 +85,7 @@ int mkdir_p(char *path, mode_t mode)
 	return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
 }
 
-int rm_rf(char *path)
+int rm_rf(const char *path)
 {
 	DIR *dir;
 	int ret = 0;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 6e8be17..c74708d 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -209,7 +209,7 @@ static inline int sane_case(int x, int high)
 }
 
 int mkdir_p(char *path, mode_t mode);
-int rm_rf(char *path);
+int rm_rf(const char *path);
 struct strlist *lsdir(const char *name, bool (*filter)(const char *, struct dirent *));
 bool lsdir_no_dot_filter(const char *name, struct dirent *d);
 int copyfile(const char *from, const char *to);

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

* [tip:perf/core] tools lib api fs: Add bpf_fs filesystem detector
  2017-01-26 21:20 ` [PATCHv3 perf/core 5/6] tools lib api fs: Add bpf_fs filesystem detector Joe Stringer
@ 2017-02-01 14:42   ` tip-bot for Joe Stringer
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, hpa, daniel, ast, acme, mingo, wangnan0, linux-kernel, joe

Commit-ID:  71dc4c30680fa7e7fd4b82352a845e2fb4d86b2b
Gitweb:     http://git.kernel.org/tip/71dc4c30680fa7e7fd4b82352a845e2fb4d86b2b
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:20:00 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:07 -0300

tools lib api fs: Add bpf_fs filesystem detector

Allow mounting of the BPF filesystem at /sys/fs/bpf.

Signed-off-by: Joe Stringer <joe@ovn.org>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-6-joe@ovn.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/api/fs/fs.c | 16 ++++++++++++++++
 tools/lib/api/fs/fs.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index f99f49e4..4b6bfc4 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -38,6 +38,10 @@
 #define HUGETLBFS_MAGIC        0x958458f6
 #endif
 
+#ifndef BPF_FS_MAGIC
+#define BPF_FS_MAGIC           0xcafe4a11
+#endif
+
 static const char * const sysfs__fs_known_mountpoints[] = {
 	"/sys",
 	0,
@@ -75,6 +79,11 @@ static const char * const hugetlbfs__known_mountpoints[] = {
 	0,
 };
 
+static const char * const bpf_fs__known_mountpoints[] = {
+	"/sys/fs/bpf",
+	0,
+};
+
 struct fs {
 	const char		*name;
 	const char * const	*mounts;
@@ -89,6 +98,7 @@ enum {
 	FS__DEBUGFS = 2,
 	FS__TRACEFS = 3,
 	FS__HUGETLBFS = 4,
+	FS__BPF_FS = 5,
 };
 
 #ifndef TRACEFS_MAGIC
@@ -121,6 +131,11 @@ static struct fs fs__entries[] = {
 		.mounts = hugetlbfs__known_mountpoints,
 		.magic	= HUGETLBFS_MAGIC,
 	},
+	[FS__BPF_FS] = {
+		.name	= "bpf",
+		.mounts = bpf_fs__known_mountpoints,
+		.magic	= BPF_FS_MAGIC,
+	},
 };
 
 static bool fs__read_mounts(struct fs *fs)
@@ -280,6 +295,7 @@ FS(procfs,  FS__PROCFS);
 FS(debugfs, FS__DEBUGFS);
 FS(tracefs, FS__TRACEFS);
 FS(hugetlbfs, FS__HUGETLBFS);
+FS(bpf_fs, FS__BPF_FS);
 
 int filename__read_int(const char *filename, int *value)
 {
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index a63269f..6b332dc 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -22,6 +22,7 @@ FS(procfs)
 FS(debugfs)
 FS(tracefs)
 FS(hugetlbfs)
+FS(bpf_fs)
 
 #undef FS
 

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

* [tip:perf/core] perf test: Add libbpf pinning test
  2017-01-26 21:20 ` [PATCHv3 perf/core 6/6] perf test: Add libbpf pinning test Joe Stringer
@ 2017-02-01 14:42   ` tip-bot for Joe Stringer
  0 siblings, 0 replies; 21+ messages in thread
From: tip-bot for Joe Stringer @ 2017-02-01 14:42 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ast, daniel, hpa, tglx, linux-kernel, joe, acme, mingo, wangnan0

Commit-ID:  a26305363d4b3a586a2d3554c22705538aa4e926
Gitweb:     http://git.kernel.org/tip/a26305363d4b3a586a2d3554c22705538aa4e926
Author:     Joe Stringer <joe@ovn.org>
AuthorDate: Thu, 26 Jan 2017 13:20:01 -0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 31 Jan 2017 16:20:08 -0300

perf test: Add libbpf pinning test

Add a test for the newly added BPF object pinning functionality.

For example:

  # tools/perf/perf test 37
    37: BPF filter                                 :
    37.1: Basic BPF filtering                      : Ok
    37.2: BPF pinning                              : Ok
    37.3: BPF prologue generation                  : Ok
    37.4: BPF relocation checker                   : Ok

  # tools/perf/perf test 37 -v 2>&1 | grep pinned
    libbpf: pinned map '/sys/fs/bpf/perf_test/flip_table'
    libbpf: pinned program '/sys/fs/bpf/perf_test/func=SyS_epoll_wait/0'

Signed-off-by: Joe Stringer <joe@ovn.org>
Requested-and-Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Wang Nan <wangnan0@huawei.com>
Cc: netdev@vger.kernel.org
Link: http://lkml.kernel.org/r/20170126212001.14103-7-joe@ovn.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/bpf.c | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 92343f4..1a04fe7 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -5,11 +5,13 @@
 #include <util/evlist.h>
 #include <linux/bpf.h>
 #include <linux/filter.h>
+#include <api/fs/fs.h>
 #include <bpf/bpf.h>
 #include "tests.h"
 #include "llvm.h"
 #include "debug.h"
 #define NR_ITERS       111
+#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
 
 #ifdef HAVE_LIBBPF_SUPPORT
 
@@ -54,6 +56,7 @@ static struct {
 	const char *msg_load_fail;
 	int (*target_func)(void);
 	int expect_result;
+	bool	pin;
 } bpf_testcase_table[] = {
 	{
 		LLVM_TESTCASE_BASE,
@@ -63,6 +66,17 @@ static struct {
 		"load bpf object failed",
 		&epoll_wait_loop,
 		(NR_ITERS + 1) / 2,
+		false,
+	},
+	{
+		LLVM_TESTCASE_BASE,
+		"BPF pinning",
+		"[bpf_pinning]",
+		"fix kbuild first",
+		"check your vmlinux setting?",
+		&epoll_wait_loop,
+		(NR_ITERS + 1) / 2,
+		true,
 	},
 #ifdef HAVE_BPF_PROLOGUE
 	{
@@ -73,6 +87,7 @@ static struct {
 		"check your vmlinux setting?",
 		&llseek_loop,
 		(NR_ITERS + 1) / 4,
+		false,
 	},
 #endif
 	{
@@ -83,6 +98,7 @@ static struct {
 		"libbpf error when dealing with relocation",
 		NULL,
 		0,
+		false,
 	},
 };
 
@@ -226,10 +242,34 @@ static int __test__bpf(int idx)
 		goto out;
 	}
 
-	if (obj)
+	if (obj) {
 		ret = do_test(obj,
 			      bpf_testcase_table[idx].target_func,
 			      bpf_testcase_table[idx].expect_result);
+		if (ret != TEST_OK)
+			goto out;
+		if (bpf_testcase_table[idx].pin) {
+			int err;
+
+			if (!bpf_fs__mount()) {
+				pr_debug("BPF filesystem not mounted\n");
+				ret = TEST_FAIL;
+				goto out;
+			}
+			err = mkdir(PERF_TEST_BPF_PATH, 0777);
+			if (err && errno != EEXIST) {
+				pr_debug("Failed to make perf_test dir: %s\n",
+					 strerror(errno));
+				ret = TEST_FAIL;
+				goto out;
+			}
+			if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
+				ret = TEST_FAIL;
+			if (rm_rf(PERF_TEST_BPF_PATH))
+				ret = TEST_FAIL;
+		}
+	}
+
 out:
 	bpf__clear();
 	return ret;

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

end of thread, other threads:[~2017-02-01 14:43 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-26 21:19 [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer
2017-01-26 21:19 ` [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs Joe Stringer
2017-01-30 20:25   ` Arnaldo Carvalho de Melo
2017-01-30 20:28     ` Arnaldo Carvalho de Melo
2017-01-30 21:16       ` Joe Stringer
2017-01-31  0:58         ` Arnaldo Carvalho de Melo
2017-01-31 16:08           ` Arnaldo Carvalho de Melo
2017-01-31 16:13             ` Arnaldo Carvalho de Melo
2017-01-31 16:42               ` Arnaldo Carvalho de Melo
2017-02-01 14:40   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-26 21:19 ` [PATCHv3 perf/core 2/6] tools lib bpf: Add bpf_map__pin() Joe Stringer
2017-02-01 14:40   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-26 21:19 ` [PATCHv3 perf/core 3/6] tools lib bpf: Add bpf_object__pin() Joe Stringer
2017-02-01 14:41   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-26 21:19 ` [PATCHv3 perf/core 4/6] tools perf util: Make rm_rf(path) argument const Joe Stringer
2017-02-01 14:41   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-26 21:20 ` [PATCHv3 perf/core 5/6] tools lib api fs: Add bpf_fs filesystem detector Joe Stringer
2017-02-01 14:42   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-26 21:20 ` [PATCHv3 perf/core 6/6] perf test: Add libbpf pinning test Joe Stringer
2017-02-01 14:42   ` [tip:perf/core] " tip-bot for Joe Stringer
2017-01-30 20:37 ` [PATCHv3 perf/core 0/6] Libbpf object pinning Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).