Commit 9fa3b473 authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'change-libbpf-print-api'

Yonghong Song says:

====================
These are patches responding to my comments for
Magnus's patch (https://patchwork.ozlabs.org/patch/1032848/).
The goal is to make pr_* macros available to other C files
than libbpf.c, and to simplify API function libbpf_set_print().

Specifically, Patch #1 used global functions
to facilitate pr_* macros in the header files so they
are available in different C files.
Patch #2 removes the global function libbpf_print_level_available()
which is added in Patch 1.
Patch #3 simplified libbpf_set_print() which takes only one print
function with a debug level argument among others.

Changelogs:
 v3 -> v4:
   . rename libbpf internal header util.h to libbpf_util.h
   . rename libbpf internal function libbpf_debug_print() to libbpf_print()
 v2 -> v3:
   . bailed out earlier in libbpf_debug_print() if __libbpf_pr is NULL
   . added missing LIBBPF_DEBUG level check in libbpf.c __base_pr().
 v1 -> v2:
   . Renamed global function libbpf_dprint() to libbpf_debug_print()
     to be more expressive.
   . Removed libbpf_dprint_level_available() as it is used only
     once in btf.c and we can remove it by optimizing for common cases.
====================
Acked-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents cc733578 6f1ae8b6
This diff is collapsed.
...@@ -55,11 +55,8 @@ struct btf_ext_header { ...@@ -55,11 +55,8 @@ struct btf_ext_header {
__u32 line_info_len; __u32 line_info_len;
}; };
typedef int (*btf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));
LIBBPF_API void btf__free(struct btf *btf); LIBBPF_API void btf__free(struct btf *btf);
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf, LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
const char *type_name); const char *type_name);
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf, LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
...@@ -70,7 +67,7 @@ LIBBPF_API int btf__fd(const struct btf *btf); ...@@ -70,7 +67,7 @@ LIBBPF_API int btf__fd(const struct btf *btf);
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset); LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf); LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
struct btf_ext *btf_ext__new(__u8 *data, __u32 size, btf_print_fn_t err_log); struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
void btf_ext__free(struct btf_ext *btf_ext); void btf_ext__free(struct btf_ext *btf_ext);
int btf_ext__reloc_func_info(const struct btf *btf, int btf_ext__reloc_func_info(const struct btf *btf,
const struct btf_ext *btf_ext, const struct btf_ext *btf_ext,
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "bpf.h" #include "bpf.h"
#include "btf.h" #include "btf.h"
#include "str_error.h" #include "str_error.h"
#include "libbpf_util.h"
#ifndef EM_BPF #ifndef EM_BPF
#define EM_BPF 247 #define EM_BPF 247
...@@ -53,39 +54,39 @@ ...@@ -53,39 +54,39 @@
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) __printf(2, 3)
static int __base_pr(const char *format, ...) static int __base_pr(enum libbpf_print_level level, const char *format, ...)
{ {
va_list args; va_list args;
int err; int err;
if (level == LIBBPF_DEBUG)
return 0;
va_start(args, format); va_start(args, format);
err = vfprintf(stderr, format, args); err = vfprintf(stderr, format, args);
va_end(args); va_end(args);
return err; return err;
} }
static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr; static __printf(2, 3) libbpf_print_fn_t __libbpf_pr = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
static __printf(1, 2) libbpf_print_fn_t __pr_debug;
#define __pr(func, fmt, ...) \
do { \
if ((func)) \
(func)("libbpf: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__) void libbpf_set_print(libbpf_print_fn_t fn)
#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__) {
#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__) __libbpf_pr = fn;
}
void libbpf_set_print(libbpf_print_fn_t warn, __printf(2, 3)
libbpf_print_fn_t info, void libbpf_print(enum libbpf_print_level level, const char *format, ...)
libbpf_print_fn_t debug)
{ {
__pr_warning = warn; va_list args;
__pr_info = info;
__pr_debug = debug; if (!__libbpf_pr)
return;
va_start(args, format);
__libbpf_pr(level, format, args);
va_end(args);
} }
#define STRERR_BUFSIZE 128 #define STRERR_BUFSIZE 128
...@@ -839,8 +840,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -839,8 +840,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
else if (strcmp(name, "maps") == 0) else if (strcmp(name, "maps") == 0)
obj->efile.maps_shndx = idx; obj->efile.maps_shndx = idx;
else if (strcmp(name, BTF_ELF_SEC) == 0) { else if (strcmp(name, BTF_ELF_SEC) == 0) {
obj->btf = btf__new(data->d_buf, data->d_size, obj->btf = btf__new(data->d_buf, data->d_size);
__pr_debug);
if (IS_ERR(obj->btf)) { if (IS_ERR(obj->btf)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_ELF_SEC, PTR_ERR(obj->btf)); BTF_ELF_SEC, PTR_ERR(obj->btf));
...@@ -915,8 +915,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) ...@@ -915,8 +915,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags)
BTF_EXT_ELF_SEC, BTF_ELF_SEC); BTF_EXT_ELF_SEC, BTF_ELF_SEC);
} else { } else {
obj->btf_ext = btf_ext__new(btf_ext_data->d_buf, obj->btf_ext = btf_ext__new(btf_ext_data->d_buf,
btf_ext_data->d_size, btf_ext_data->d_size);
__pr_debug);
if (IS_ERR(obj->btf_ext)) { if (IS_ERR(obj->btf_ext)) {
pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n",
BTF_EXT_ELF_SEC, BTF_EXT_ELF_SEC,
......
...@@ -47,17 +47,17 @@ enum libbpf_errno { ...@@ -47,17 +47,17 @@ enum libbpf_errno {
LIBBPF_API int libbpf_strerror(int err, char *buf, size_t size); LIBBPF_API int libbpf_strerror(int err, char *buf, size_t size);
/* enum libbpf_print_level {
* __printf is defined in include/linux/compiler-gcc.h. However, LIBBPF_WARN,
* it would be better if libbpf.h didn't depend on Linux header files. LIBBPF_INFO,
* So instead of __printf, here we use gcc attribute directly. LIBBPF_DEBUG,
*/ };
typedef int (*libbpf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2))); typedef int (*libbpf_print_fn_t)(enum libbpf_print_level level,
const char *, ...)
__attribute__((format(printf, 2, 3)));
LIBBPF_API void libbpf_set_print(libbpf_print_fn_t warn, LIBBPF_API void libbpf_set_print(libbpf_print_fn_t fn);
libbpf_print_fn_t info,
libbpf_print_fn_t debug);
/* Hide internal to user */ /* Hide internal to user */
struct bpf_object; struct bpf_object;
......
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
/* Copyright (c) 2019 Facebook */
#ifndef __LIBBPF_LIBBPF_UTIL_H
#define __LIBBPF_LIBBPF_UTIL_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void libbpf_print(enum libbpf_print_level level,
const char *format, ...)
__attribute__((format(printf, 2, 3)));
#define __pr(level, fmt, ...) \
do { \
libbpf_print(level, "libbpf: " fmt, ##__VA_ARGS__); \
} while (0)
#define pr_warning(fmt, ...) __pr(LIBBPF_WARN, fmt, ##__VA_ARGS__)
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
...@@ -8,11 +8,11 @@ ...@@ -8,11 +8,11 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/* libbpf.h */ /* libbpf.h */
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
/* bpf.h */ /* bpf.h */
bpf_prog_get_fd_by_id(0); bpf_prog_get_fd_by_id(0);
/* btf.h */ /* btf.h */
btf__new(NULL, 0, NULL); btf__new(NULL, 0);
} }
...@@ -24,21 +24,17 @@ ...@@ -24,21 +24,17 @@
#include "llvm-utils.h" #include "llvm-utils.h"
#include "c++/clang-c.h" #include "c++/clang-c.h"
#define DEFINE_PRINT_FN(name, level) \ static int libbpf_perf_print(enum libbpf_print_level level __attribute__((unused)),
static int libbpf_##name(const char *fmt, ...) \ const char *fmt, ...)
{ \ {
va_list args; \ va_list args;
int ret; \ int ret;
\
va_start(args, fmt); \
ret = veprintf(level, verbose, pr_fmt(fmt), args);\
va_end(args); \
return ret; \
}
DEFINE_PRINT_FN(warning, 1) va_start(args, fmt);
DEFINE_PRINT_FN(info, 1) ret = veprintf(1, verbose, pr_fmt(fmt), args);
DEFINE_PRINT_FN(debug, 1) va_end(args);
return ret;
}
struct bpf_prog_priv { struct bpf_prog_priv {
bool is_tp; bool is_tp;
...@@ -59,9 +55,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name) ...@@ -59,9 +55,7 @@ bpf__prepare_load_buffer(void *obj_buf, size_t obj_buf_sz, const char *name)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
...@@ -79,9 +73,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source) ...@@ -79,9 +73,7 @@ struct bpf_object *bpf__prepare_load(const char *filename, bool source)
struct bpf_object *obj; struct bpf_object *obj;
if (!libbpf_initialized) { if (!libbpf_initialized) {
libbpf_set_print(libbpf_warning, libbpf_set_print(libbpf_perf_print);
libbpf_info,
libbpf_debug);
libbpf_initialized = true; libbpf_initialized = true;
} }
......
...@@ -54,8 +54,9 @@ static int count_result(int err) ...@@ -54,8 +54,9 @@ static int count_result(int err)
#define __printf(a, b) __attribute__((format(printf, a, b))) #define __printf(a, b) __attribute__((format(printf, a, b)))
__printf(1, 2) __printf(2, 3)
static int __base_pr(const char *format, ...) static int __base_pr(enum libbpf_print_level level __attribute__((unused)),
const char *format, ...)
{ {
va_list args; va_list args;
int err; int err;
...@@ -5650,7 +5651,7 @@ int main(int argc, char **argv) ...@@ -5650,7 +5651,7 @@ int main(int argc, char **argv)
return err; return err;
if (args.always_log) if (args.always_log)
libbpf_set_print(__base_pr, __base_pr, __base_pr); libbpf_set_print(__base_pr);
if (args.raw_test) if (args.raw_test)
err |= test_raw(); err |= test_raw();
......
...@@ -34,23 +34,22 @@ static void usage(char *argv[]) ...@@ -34,23 +34,22 @@ static void usage(char *argv[])
printf("\n"); printf("\n");
} }
#define DEFINE_PRINT_FN(name, enabled) \ static bool debug = 0;
static int libbpf_##name(const char *fmt, ...) \ static int libbpf_debug_print(enum libbpf_print_level level,
{ \ const char *fmt, ...)
va_list args; \ {
int ret; \ va_list args;
\ int ret;
va_start(args, fmt); \
if (enabled) { \ if (level == LIBBPF_DEBUG && !debug)
fprintf(stderr, "[" #name "] "); \ return 0;
ret = vfprintf(stderr, fmt, args); \
} \ va_start(args, fmt);
va_end(args); \ fprintf(stderr, "[%d] ", level);
return ret; \ ret = vfprintf(stderr, fmt, args);
va_end(args);
return ret;
} }
DEFINE_PRINT_FN(warning, 1)
DEFINE_PRINT_FN(info, 1)
DEFINE_PRINT_FN(debug, 1)
#define EXIT_FAIL_LIBBPF EXIT_FAILURE #define EXIT_FAIL_LIBBPF EXIT_FAILURE
#define EXIT_FAIL_OPTION 2 #define EXIT_FAIL_OPTION 2
...@@ -120,15 +119,14 @@ int main(int argc, char **argv) ...@@ -120,15 +119,14 @@ int main(int argc, char **argv)
int longindex = 0; int longindex = 0;
int opt; int opt;
libbpf_set_print(libbpf_warning, libbpf_info, NULL); libbpf_set_print(libbpf_debug_print);
/* Parse commands line args */ /* Parse commands line args */
while ((opt = getopt_long(argc, argv, "hDq", while ((opt = getopt_long(argc, argv, "hDq",
long_options, &longindex)) != -1) { long_options, &longindex)) != -1) {
switch (opt) { switch (opt) {
case 'D': case 'D':
libbpf_set_print(libbpf_warning, libbpf_info, debug = 1;
libbpf_debug);
break; break;
case 'q': /* Use in scripting mode */ case 'q': /* Use in scripting mode */
verbose = 0; verbose = 0;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h>
#include <time.h> #include <time.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -1783,6 +1784,21 @@ static void test_task_fd_query_tp(void) ...@@ -1783,6 +1784,21 @@ static void test_task_fd_query_tp(void)
"sys_enter_read"); "sys_enter_read");
} }
static int libbpf_debug_print(enum libbpf_print_level level,
const char *format, ...)
{
va_list args;
int ret;
if (level == LIBBPF_DEBUG)
return 0;
va_start(args, format);
ret = vfprintf(stderr, format, args);
va_end(args);
return ret;
}
static void test_reference_tracking() static void test_reference_tracking()
{ {
const char *file = "./test_sk_lookup_kern.o"; const char *file = "./test_sk_lookup_kern.o";
...@@ -1809,9 +1825,9 @@ static void test_reference_tracking() ...@@ -1809,9 +1825,9 @@ static void test_reference_tracking()
/* Expect verifier failure if test name has 'fail' */ /* Expect verifier failure if test name has 'fail' */
if (strstr(title, "fail") != NULL) { if (strstr(title, "fail") != NULL) {
libbpf_set_print(NULL, NULL, NULL); libbpf_set_print(NULL);
err = !bpf_program__load(prog, "GPL", 0); err = !bpf_program__load(prog, "GPL", 0);
libbpf_set_print(printf, printf, NULL); libbpf_set_print(libbpf_debug_print);
} else { } else {
err = bpf_program__load(prog, "GPL", 0); err = bpf_program__load(prog, "GPL", 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment