Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1567723 > unrolled thread

[PATCHv3 perf/core 0/6] Libbpf object pinning

Started byJoe Stringer <joe@ovn.org>
First post2017-01-26 22:30 +0100
Last post2017-01-30 21:40 +0100
Articles 11 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCHv3 perf/core 0/6] Libbpf object pinning Joe Stringer <joe@ovn.org> - 2017-01-26 22:30 +0100
    [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs. Joe Stringer <joe@ovn.org> - 2017-01-26 22:30 +0100
      Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-30 21:30 +0100
        Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs. Joe Stringer <joe@ovn.org> - 2017-01-30 22:20 +0100
          Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-31 02:10 +0100
            Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-31 17:10 +0100
              Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-31 17:20 +0100
                Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-31 17:50 +0100
      Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning  APIs. Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-30 21:30 +0100
      [tip:perf/core] tools lib bpf: Add BPF program pinning APIs tip-bot for Joe Stringer <tipbot@zytor.com> - 2017-02-01 15:50 +0100
    Re: [PATCHv3 perf/core 0/6] Libbpf object pinning Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-01-30 21:40 +0100

#1567723 — [PATCHv3 perf/core 0/6] Libbpf object pinning

FromJoe Stringer <joe@ovn.org>
Date2017-01-26 22:30 +0100
Subject[PATCHv3 perf/core 0/6] Libbpf object pinning
Message-ID<t3ZMe-3YK-3@gated-at.bofh.it>
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

[toc] | [next] | [standalone]


#1567726 — [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromJoe Stringer <joe@ovn.org>
Date2017-01-26 22:30 +0100
Subject[PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t3ZMf-3YK-31@gated-at.bofh.it>
In reply to#1567723
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

[toc] | [prev] | [next] | [standalone]


#1570095 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-30 21:30 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5qKm-8tx-5@gated-at.bofh.it>
In reply to#1567726
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.
---

[toc] | [prev] | [next] | [standalone]


#1570122 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromJoe Stringer <joe@ovn.org>
Date2017-01-30 22:20 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5rwJ-x1-9@gated-at.bofh.it>
In reply to#1570095
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!

[toc] | [prev] | [next] | [standalone]


#1570228 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-31 02:10 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5v7k-2HW-11@gated-at.bofh.it>
In reply to#1570122
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

[toc] | [prev] | [next] | [standalone]


#1570855 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-31 17:10 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5Jaj-2Mv-25@gated-at.bofh.it>
In reply to#1570228
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.)

[toc] | [prev] | [next] | [standalone]


#1570870 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-31 17:20 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5JjY-2Qa-23@gated-at.bofh.it>
In reply to#1570855
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

[toc] | [prev] | [next] | [standalone]


#1570896 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-31 17:50 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5JMZ-2ZV-15@gated-at.bofh.it>
In reply to#1570870
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

[toc] | [prev] | [next] | [standalone]


#1570102 — Re: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-30 21:30 +0100
SubjectRe: [PATCHv3 perf/core 1/6] tools lib bpf: Add BPF program pinning APIs.
Message-ID<t5qKm-8tx-7@gated-at.bofh.it>
In reply to#1567726
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

[toc] | [prev] | [next] | [standalone]


#1571620 — [tip:perf/core] tools lib bpf: Add BPF program pinning APIs

Fromtip-bot for Joe Stringer <tipbot@zytor.com>
Date2017-02-01 15:50 +0100
Subject[tip:perf/core] tools lib bpf: Add BPF program pinning APIs
Message-ID<t64or-7aO-41@gated-at.bofh.it>
In reply to#1567726
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;
 

[toc] | [prev] | [next] | [standalone]


#1570103

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-01-30 21:40 +0100
Message-ID<t5qU1-4V-3@gated-at.bofh.it>
In reply to#1567723
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

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web