1. 20 11月, 2021 1 次提交
  2. 19 11月, 2021 1 次提交
  3. 12 11月, 2021 2 次提交
  4. 08 11月, 2021 2 次提交
    • A
      libbpf: Remove deprecation attribute from struct bpf_prog_prep_result · 5c5edcde
      Andrii Nakryiko 提交于
      This deprecation annotation has no effect because for struct deprecation
      attribute has to be declared after struct definition. But instead of
      moving it to the end of struct definition, remove it. When deprecation
      will go in effect at libbpf v0.7, this deprecation attribute will cause
      libbpf's own source code compilation to trigger deprecation warnings,
      which is unavoidable because libbpf still has to support that API.
      
      So keep deprecation of APIs, but don't mark structs used in API as
      deprecated.
      
      Fixes: e21d585c ("libbpf: Deprecate multi-instance bpf_program APIs")
      Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Acked-by: NDave Marchevsky <davemarchevsky@fb.com>
      Link: https://lore.kernel.org/bpf/20211103220845.2676888-8-andrii@kernel.org
      5c5edcde
    • A
      libbpf: Unify low-level BPF_PROG_LOAD APIs into bpf_prog_load() · d10ef2b8
      Andrii Nakryiko 提交于
      Add a new unified OPTS-based low-level API for program loading,
      bpf_prog_load() ([0]).  bpf_prog_load() accepts few "mandatory"
      parameters as input arguments (program type, name, license,
      instructions) and all the other optional (as in not required to specify
      for all types of BPF programs) fields into struct bpf_prog_load_opts.
      
      This makes all the other non-extensible APIs variant for BPF_PROG_LOAD
      obsolete and they are slated for deprecation in libbpf v0.7:
        - bpf_load_program();
        - bpf_load_program_xattr();
        - bpf_verify_program().
      
      Implementation-wise, internal helper libbpf__bpf_prog_load is refactored
      to become a public bpf_prog_load() API. struct bpf_prog_load_params used
      internally is replaced by public struct bpf_prog_load_opts.
      
      Unfortunately, while conceptually all this is pretty straightforward,
      the biggest complication comes from the already existing bpf_prog_load()
      *high-level* API, which has nothing to do with BPF_PROG_LOAD command.
      
      We try really hard to have a new API named bpf_prog_load(), though,
      because it maps naturally to BPF_PROG_LOAD command.
      
      For that, we rename old bpf_prog_load() into bpf_prog_load_deprecated()
      and mark it as COMPAT_VERSION() for shared library users compiled
      against old version of libbpf. Statically linked users and shared lib
      users compiled against new version of libbpf headers will get "rerouted"
      to bpf_prog_deprecated() through a macro helper that decides whether to
      use new or old bpf_prog_load() based on number of input arguments (see
      ___libbpf_overload in libbpf_common.h).
      
      To test that existing
      bpf_prog_load()-using code compiles and works as expected, I've compiled
      and ran selftests as is. I had to remove (locally) selftest/bpf/Makefile
      -Dbpf_prog_load=bpf_prog_test_load hack because it was conflicting with
      the macro-based overload approach. I don't expect anyone else to do
      something like this in practice, though. This is testing-specific way to
      replace bpf_prog_load() calls with special testing variant of it, which
      adds extra prog_flags value. After testing I kept this selftests hack,
      but ensured that we use a new bpf_prog_load_deprecated name for this.
      
      This patch also marks bpf_prog_load() and bpf_prog_load_xattr() as deprecated.
      bpf_object interface has to be used for working with struct bpf_program.
      Libbpf doesn't support loading just a bpf_program.
      
      The silver lining is that when we get to libbpf 1.0 all these
      complication will be gone and we'll have one clean bpf_prog_load()
      low-level API with no backwards compatibility hackery surrounding it.
      
        [0] Closes: https://github.com/libbpf/libbpf/issues/284Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211103220845.2676888-4-andrii@kernel.org
      d10ef2b8
  5. 04 11月, 2021 2 次提交
  6. 29 10月, 2021 1 次提交
  7. 28 10月, 2021 1 次提交
  8. 26 10月, 2021 3 次提交
    • A
      libbpf: Deprecate ambiguously-named bpf_program__size() API · c4813e96
      Andrii Nakryiko 提交于
      The name of the API doesn't convey clearly that this size is in number
      of bytes (there needed to be a separate comment to make this clear in
      libbpf.h). Further, measuring the size of BPF program in bytes is not
      exactly the best fit, because BPF programs always consist of 8-byte
      instructions. As such, bpf_program__insn_cnt() is a better alternative
      in pretty much any imaginable case.
      
      So schedule bpf_program__size() deprecation starting from v0.7 and it
      will be removed in libbpf 1.0.
      Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211025224531.1088894-5-andrii@kernel.org
      c4813e96
    • A
      libbpf: Deprecate multi-instance bpf_program APIs · e21d585c
      Andrii Nakryiko 提交于
      Schedule deprecation of a set of APIs that are related to multi-instance
      bpf_programs:
        - bpf_program__set_prep() ([0]);
        - bpf_program__{set,unset}_instance() ([1]);
        - bpf_program__nth_fd().
      
      These APIs are obscure, very niche, and don't seem to be used much in
      practice. bpf_program__set_prep() is pretty useless for anything but the
      simplest BPF programs, as it doesn't allow to adjust BPF program load
      attributes, among other things. In short, it already bitrotted and will
      bitrot some more if not removed.
      
      With bpf_program__insns() API, which gives access to post-processed BPF
      program instructions of any given entry-point BPF program, it's now
      possible to do whatever necessary adjustments were possible with
      set_prep() API before, but also more. Given any such use case is
      automatically an advanced use case, requiring users to stick to
      low-level bpf_prog_load() APIs and managing their own prog FDs is
      reasonable.
      
        [0] Closes: https://github.com/libbpf/libbpf/issues/299
        [1] Closes: https://github.com/libbpf/libbpf/issues/300Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211025224531.1088894-4-andrii@kernel.org
      e21d585c
    • A
      libbpf: Add ability to fetch bpf_program's underlying instructions · 65a7fa2e
      Andrii Nakryiko 提交于
      Add APIs providing read-only access to bpf_program BPF instructions ([0]).
      This is useful for diagnostics purposes, but it also allows a cleaner
      support for cloning BPF programs after libbpf did all the FD resolution
      and CO-RE relocations, subprog instructions appending, etc. Currently,
      cloning BPF program is possible only through hijacking a half-broken
      bpf_program__set_prep() API, which doesn't really work well for anything
      but most primitive programs. For instance, set_prep() API doesn't allow
      adjusting BPF program load parameters which are necessary for loading
      fentry/fexit BPF programs (the case where BPF program cloning is
      a necessity if doing some sort of mass-attachment functionality).
      
      Given bpf_program__set_prep() API is set to be deprecated, having
      a cleaner alternative is a must. libbpf internally already keeps track
      of linear array of struct bpf_insn, so it's not hard to expose it. The
      only gotcha is that libbpf previously freed instructions array during
      bpf_object load time, which would make this API much less useful overall,
      because in between bpf_object__open() and bpf_object__load() a lot of
      changes to instructions are done by libbpf.
      
      So this patch makes libbpf hold onto prog->insns array even after BPF
      program loading. I think this is a small price for added functionality
      and improved introspection of BPF program code.
      
      See retsnoop PR ([1]) for how it can be used in practice and code
      savings compared to relying on bpf_program__set_prep().
      
        [0] Closes: https://github.com/libbpf/libbpf/issues/298
        [1] https://github.com/anakryiko/retsnoop/pull/1Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20211025224531.1088894-3-andrii@kernel.org
      65a7fa2e
  9. 07 10月, 2021 2 次提交
  10. 22 9月, 2021 1 次提交
    • A
      libbpf: Refactor and simplify legacy kprobe code · 46ed5fc3
      Andrii Nakryiko 提交于
      Refactor legacy kprobe handling code to follow the same logic as uprobe
      legacy logic added in the next patchs:
        - add append_to_file() helper that makes it simpler to work with
          tracefs file-based interface for creating and deleting probes;
        - move out probe/event name generation outside of the code that
          adds/removes it, which simplifies bookkeeping significantly;
        - change the probe name format to start with "libbpf_" prefix and
          include offset within kernel function;
        - switch 'unsigned long' to 'size_t' for specifying kprobe offsets,
          which is consistent with how uprobes define that, simplifies
          printf()-ing internally, and also avoids unnecessary complications on
          architectures where sizeof(long) != sizeof(void *).
      
      This patch also implicitly fixes the problem with invalid open() error
      handling present in poke_kprobe_events(), which (the function) this
      patch removes.
      
      Fixes: ca304b40 ("libbpf: Introduce legacy kprobe events support")
      Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20210921210036.1545557-4-andrii@kernel.org
      46ed5fc3
  11. 21 9月, 2021 1 次提交
  12. 18 9月, 2021 3 次提交
  13. 08 9月, 2021 1 次提交
  14. 17 8月, 2021 2 次提交
  15. 24 7月, 2021 1 次提交
  16. 23 7月, 2021 1 次提交
  17. 17 7月, 2021 1 次提交
  18. 26 5月, 2021 1 次提交
  19. 19 5月, 2021 2 次提交
    • A
      libbpf: Introduce bpf_map__initial_value(). · 7723256b
      Alexei Starovoitov 提交于
      Introduce bpf_map__initial_value() to read initial contents
      of mmaped data/rodata/bss maps.
      Note that bpf_map__set_initial_value() doesn't allow modifying
      kconfig map while bpf_map__initial_value() allows reading
      its values.
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20210514003623.28033-17-alexei.starovoitov@gmail.com
      7723256b
    • A
      libbpf: Generate loader program out of BPF ELF file. · 67234743
      Alexei Starovoitov 提交于
      The BPF program loading process performed by libbpf is quite complex
      and consists of the following steps:
      "open" phase:
      - parse elf file and remember relocations, sections
      - collect externs and ksyms including their btf_ids in prog's BTF
      - patch BTF datasec (since llvm couldn't do it)
      - init maps (old style map_def, BTF based, global data map, kconfig map)
      - collect relocations against progs and maps
      "load" phase:
      - probe kernel features
      - load vmlinux BTF
      - resolve externs (kconfig and ksym)
      - load program BTF
      - init struct_ops
      - create maps
      - apply CO-RE relocations
      - patch ld_imm64 insns with src_reg=PSEUDO_MAP, PSEUDO_MAP_VALUE, PSEUDO_BTF_ID
      - reposition subprograms and adjust call insns
      - sanitize and load progs
      
      During this process libbpf does sys_bpf() calls to load BTF, create maps,
      populate maps and finally load programs.
      Instead of actually doing the syscalls generate a trace of what libbpf
      would have done and represent it as the "loader program".
      The "loader program" consists of single map with:
      - union bpf_attr(s)
      - BTF bytes
      - map value bytes
      - insns bytes
      and single bpf program that passes bpf_attr(s) and data into bpf_sys_bpf() helper.
      Executing such "loader program" via bpf_prog_test_run() command will
      replay the sequence of syscalls that libbpf would have done which will result
      the same maps created and programs loaded as specified in the elf file.
      The "loader program" removes libelf and majority of libbpf dependency from
      program loading process.
      
      kconfig, typeless ksym, struct_ops and CO-RE are not supported yet.
      
      The order of relocate_data and relocate_calls had to change, so that
      bpf_gen__prog_load() can see all relocations for a given program with
      correct insn_idx-es.
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Acked-by: NAndrii Nakryiko <andrii@kernel.org>
      Link: https://lore.kernel.org/bpf/20210514003623.28033-15-alexei.starovoitov@gmail.com
      67234743
  20. 17 5月, 2021 1 次提交
    • K
      libbpf: Add low level TC-BPF management API · 715c5ce4
      Kumar Kartikeya Dwivedi 提交于
      This adds functions that wrap the netlink API used for adding, manipulating,
      and removing traffic control filters.
      
      The API summary:
      
      A bpf_tc_hook represents a location where a TC-BPF filter can be attached.
      This means that creating a hook leads to creation of the backing qdisc,
      while destruction either removes all filters attached to a hook, or destroys
      qdisc if requested explicitly (as discussed below).
      
      The TC-BPF API functions operate on this bpf_tc_hook to attach, replace,
      query, and detach tc filters. All functions return 0 on success, and a
      negative error code on failure.
      
      bpf_tc_hook_create - Create a hook
      Parameters:
      	@hook - Cannot be NULL, ifindex > 0, attach_point must be set to
      		proper enum constant. Note that parent must be unset when
      		attach_point is one of BPF_TC_INGRESS or BPF_TC_EGRESS. Note
      		that as an exception BPF_TC_INGRESS|BPF_TC_EGRESS is also a
      		valid value for attach_point.
      
      		Returns -EOPNOTSUPP when hook has attach_point as BPF_TC_CUSTOM.
      
      bpf_tc_hook_destroy - Destroy a hook
      Parameters:
      	@hook - Cannot be NULL. The behaviour depends on value of
      		attach_point. If BPF_TC_INGRESS, all filters attached to
      		the ingress hook will be detached. If BPF_TC_EGRESS, all
      		filters attached to the egress hook will be detached. If
      		BPF_TC_INGRESS|BPF_TC_EGRESS, the clsact qdisc will be
      		deleted, also detaching all filters. As before, parent must
      		be unset for these attach_points, and set for BPF_TC_CUSTOM.
      
      		It is advised that if the qdisc is operated on by many programs,
      		then the program at least check that there are no other existing
      		filters before deleting the clsact qdisc. An example is shown
      		below:
      
      		DECLARE_LIBBPF_OPTS(bpf_tc_hook, .ifindex = if_nametoindex("lo"),
      				    .attach_point = BPF_TC_INGRESS);
      		/* set opts as NULL, as we're not really interested in
      		 * getting any info for a particular filter, but just
      	 	 * detecting its presence.
      		 */
      		r = bpf_tc_query(&hook, NULL);
      		if (r == -ENOENT) {
      			/* no filters */
      			hook.attach_point = BPF_TC_INGRESS|BPF_TC_EGREESS;
      			return bpf_tc_hook_destroy(&hook);
      		} else {
      			/* failed or r == 0, the latter means filters do exist */
      			return r;
      		}
      
      		Note that there is a small race between checking for no
      		filters and deleting the qdisc. This is currently unavoidable.
      
      		Returns -EOPNOTSUPP when hook has attach_point as BPF_TC_CUSTOM.
      
      bpf_tc_attach - Attach a filter to a hook
      Parameters:
      	@hook - Cannot be NULL. Represents the hook the filter will be
      		attached to. Requirements for ifindex and attach_point are
      		same as described in bpf_tc_hook_create, but BPF_TC_CUSTOM
      		is also supported.  In that case, parent must be set to the
      		handle where the filter will be attached (using BPF_TC_PARENT).
      		E.g. to set parent to 1:16 like in tc command line, the
      		equivalent would be BPF_TC_PARENT(1, 16).
      
      	@opts - Cannot be NULL. The following opts are optional:
      		* handle   - The handle of the filter
      		* priority - The priority of the filter
      			     Must be >= 0 and <= UINT16_MAX
      		Note that when left unset, they will be auto-allocated by
      		the kernel. The following opts must be set:
      		* prog_fd - The fd of the loaded SCHED_CLS prog
      		The following opts must be unset:
      		* prog_id - The ID of the BPF prog
      		The following opts are optional:
      		* flags - Currently only BPF_TC_F_REPLACE is allowed. It
      			  allows replacing an existing filter instead of
      			  failing with -EEXIST.
      		The following opts will be filled by bpf_tc_attach on a
      		successful attach operation if they are unset:
      		* handle   - The handle of the attached filter
      		* priority - The priority of the attached filter
      		* prog_id  - The ID of the attached SCHED_CLS prog
      		This way, the user can know what the auto allocated values
      		for optional opts like handle and priority are for the newly
      		attached filter, if they were unset.
      
      		Note that some other attributes are set to fixed default
      		values listed below (this holds for all bpf_tc_* APIs):
      		protocol as ETH_P_ALL, direct action mode, chain index of 0,
      		and class ID of 0 (this can be set by writing to the
      		skb->tc_classid field from the BPF program).
      
      bpf_tc_detach
      Parameters:
      	@hook - Cannot be NULL. Represents the hook the filter will be
      		detached from. Requirements are same as described above
      		in bpf_tc_attach.
      
      	@opts - Cannot be NULL. The following opts must be set:
      		* handle, priority
      		The following opts must be unset:
      		* prog_fd, prog_id, flags
      
      bpf_tc_query
      Parameters:
      	@hook - Cannot be NULL. Represents the hook where the filter lookup will
      		be performed. Requirements are same as described above in
      		bpf_tc_attach().
      
      	@opts - Cannot be NULL. The following opts must be set:
      		* handle, priority
      		The following opts must be unset:
      		* prog_fd, prog_id, flags
      		The following fields will be filled by bpf_tc_query upon a
      		successful lookup:
      		* prog_id
      
      Some usage examples (using BPF skeleton infrastructure):
      
      BPF program (test_tc_bpf.c):
      
      	#include <linux/bpf.h>
      	#include <bpf/bpf_helpers.h>
      
      	SEC("classifier")
      	int cls(struct __sk_buff *skb)
      	{
      		return 0;
      	}
      
      Userspace loader:
      
      	struct test_tc_bpf *skel = NULL;
      	int fd, r;
      
      	skel = test_tc_bpf__open_and_load();
      	if (!skel)
      		return -ENOMEM;
      
      	fd = bpf_program__fd(skel->progs.cls);
      
      	DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex =
      			    if_nametoindex("lo"), .attach_point =
      			    BPF_TC_INGRESS);
      	/* Create clsact qdisc */
      	r = bpf_tc_hook_create(&hook);
      	if (r < 0)
      		goto end;
      
      	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts, .prog_fd = fd);
      	r = bpf_tc_attach(&hook, &opts);
      	if (r < 0)
      		goto end;
      	/* Print the auto allocated handle and priority */
      	printf("Handle=%u", opts.handle);
      	printf("Priority=%u", opts.priority);
      
      	opts.prog_fd = opts.prog_id = 0;
      	bpf_tc_detach(&hook, &opts);
      end:
      	test_tc_bpf__destroy(skel);
      
      This is equivalent to doing the following using tc command line:
        # tc qdisc add dev lo clsact
        # tc filter add dev lo ingress bpf obj foo.o sec classifier da
        # tc filter del dev lo ingress handle <h> prio <p> bpf
      ... where the handle and priority can be found using:
        # tc filter show dev lo ingress
      
      Another example replacing a filter (extending prior example):
      
      	/* We can also choose both (or one), let's try replacing an
      	 * existing filter.
      	 */
      	DECLARE_LIBBPF_OPTS(bpf_tc_opts, replace_opts, .handle =
      			    opts.handle, .priority = opts.priority,
      			    .prog_fd = fd);
      	r = bpf_tc_attach(&hook, &replace_opts);
      	if (r == -EEXIST) {
      		/* Expected, now use BPF_TC_F_REPLACE to replace it */
      		replace_opts.flags = BPF_TC_F_REPLACE;
      		return bpf_tc_attach(&hook, &replace_opts);
      	} else if (r < 0) {
      		return r;
      	}
      	/* There must be no existing filter with these
      	 * attributes, so cleanup and return an error.
      	 */
      	replace_opts.prog_fd = replace_opts.prog_id = 0;
      	bpf_tc_detach(&hook, &replace_opts);
      	return -1;
      
      To obtain info of a particular filter:
      
      	/* Find info for filter with handle 1 and priority 50 */
      	DECLARE_LIBBPF_OPTS(bpf_tc_opts, info_opts, .handle = 1,
      			    .priority = 50);
      	r = bpf_tc_query(&hook, &info_opts);
      	if (r == -ENOENT)
      		printf("Filter not found");
      	else if (r < 0)
      		return r;
      	printf("Prog ID: %u", info_opts.prog_id);
      	return 0;
      Signed-off-by: NKumar Kartikeya Dwivedi <memxor@gmail.com>
      Co-developed-by: Daniel Borkmann <daniel@iogearbox.net> # libbpf API design
      [ Daniel: also did major patch cleanup ]
      Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
      Reviewed-by: NToke Høiland-Jørgensen <toke@redhat.com>
      Link: https://lore.kernel.org/bpf/20210512103451.989420-3-memxor@gmail.com
      715c5ce4
  21. 12 5月, 2021 1 次提交
  22. 09 4月, 2021 1 次提交
  23. 26 3月, 2021 2 次提交
  24. 19 3月, 2021 1 次提交
    • A
      libbpf: Add BPF static linker APIs · faf6ed32
      Andrii Nakryiko 提交于
      Introduce BPF static linker APIs to libbpf. BPF static linker allows to
      perform static linking of multiple BPF object files into a single combined
      resulting object file, preserving all the BPF programs, maps, global
      variables, etc.
      
      Data sections (.bss, .data, .rodata, .maps, maps, etc) with the same name are
      concatenated together. Similarly, code sections are also concatenated. All the
      symbols and ELF relocations are also concatenated in their respective ELF
      sections and are adjusted accordingly to the new object file layout.
      
      Static variables and functions are handled correctly as well, adjusting BPF
      instructions offsets to reflect new variable/function offset within the
      combined ELF section. Such relocations are referencing STT_SECTION symbols and
      that stays intact.
      
      Data sections in different files can have different alignment requirements, so
      that is taken care of as well, adjusting sizes and offsets as necessary to
      satisfy both old and new alignment requirements.
      
      DWARF data sections are stripped out, currently. As well as LLLVM_ADDRSIG
      section, which is ignored by libbpf in bpf_object__open() anyways. So, in
      a way, BPF static linker is an analogue to `llvm-strip -g`, which is a pretty
      nice property, especially if resulting .o file is then used to generate BPF
      skeleton.
      
      Original string sections are ignored and instead we construct our own set of
      unique strings using libbpf-internal `struct strset` API.
      
      To reduce the size of the patch, all the .BTF and .BTF.ext processing was
      moved into a separate patch.
      
      The high-level API consists of just 4 functions:
        - bpf_linker__new() creates an instance of BPF static linker. It accepts
          output filename and (currently empty) options struct;
        - bpf_linker__add_file() takes input filename and appends it to the already
          processed ELF data; it can be called multiple times, one for each BPF
          ELF object file that needs to be linked in;
        - bpf_linker__finalize() needs to be called to dump final ELF contents into
          the output file, specified when bpf_linker was created; after
          bpf_linker__finalize() is called, no more bpf_linker__add_file() and
          bpf_linker__finalize() calls are allowed, they will return error;
        - regardless of whether bpf_linker__finalize() was called or not,
          bpf_linker__free() will free up all the used resources.
      
      Currently, BPF static linker doesn't resolve cross-object file references
      (extern variables and/or functions). This will be added in the follow up patch
      set.
      Signed-off-by: NAndrii Nakryiko <andrii@kernel.org>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Link: https://lore.kernel.org/bpf/20210318194036.3521577-7-andrii@kernel.org
      faf6ed32
  25. 17 3月, 2021 1 次提交
  26. 15 12月, 2020 1 次提交
  27. 30 9月, 2020 1 次提交
  28. 04 9月, 2020 1 次提交
  29. 22 8月, 2020 1 次提交
    • A
      libbpf: Add perf_buffer APIs for better integration with outside epoll loop · dca5612f
      Andrii Nakryiko 提交于
      Add a set of APIs to perf_buffer manage to allow applications to integrate
      perf buffer polling into existing epoll-based infrastructure. One example is
      applications using libevent already and wanting to plug perf_buffer polling,
      instead of relying on perf_buffer__poll() and waste an extra thread to do it.
      But perf_buffer is still extremely useful to set up and consume perf buffer
      rings even for such use cases.
      
      So to accomodate such new use cases, add three new APIs:
        - perf_buffer__buffer_cnt() returns number of per-CPU buffers maintained by
          given instance of perf_buffer manager;
        - perf_buffer__buffer_fd() returns FD of perf_event corresponding to
          a specified per-CPU buffer; this FD is then polled independently;
        - perf_buffer__consume_buffer() consumes data from single per-CPU buffer,
          identified by its slot index.
      
      To support a simpler, but less efficient, way to integrate perf_buffer into
      external polling logic, also expose underlying epoll FD through
      perf_buffer__epoll_fd() API. It will need to be followed by
      perf_buffer__poll(), wasting extra syscall, or perf_buffer__consume(), wasting
      CPU to iterate buffers with no data. But could be simpler and more convenient
      for some cases.
      
      These APIs allow for great flexiblity, but do not sacrifice general usability
      of perf_buffer.
      
      Also exercise and check new APIs in perf_buffer selftest.
      Signed-off-by: NAndrii Nakryiko <andriin@fb.com>
      Signed-off-by: NAlexei Starovoitov <ast@kernel.org>
      Reviewed-by: NAlan Maguire <alan.maguire@oracle.com>
      Link: https://lore.kernel.org/bpf/20200821165927.849538-1-andriin@fb.com
      dca5612f