netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros
@ 2019-10-02 21:50 Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 1/7] selftests/bpf: undo GCC-specific bpf_helpers.h changes Andrii Nakryiko
                   ` (6 more replies)
  0 siblings, 7 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

This patch set makes bpf_helpers.h and bpf_endian.h a part of libbpf itself
for consumption by user BPF programs, not just selftests. It also splits off
tracing helpers into bpf_tracing.h, which also becomes part of libbpf. Some of
the legacy stuff (BPF_ANNOTATE_KV_PAIR, load_{byte,half,word}, bpf_map_def
with unsupported fields, etc, is extracted into selftests-only bpf_legacy.h.
All the selftests and samples are switched to use libbpf's headers and
selftests' ones are removed.

As part of this patch set we also add BPF_CORE_READ variadic macros, that are
simplifying BPF CO-RE reads, especially the ones that have to follow few
pointers. E.g., what in non-BPF world (and when using BCC) would be:

int x = s->a->b.c->d; /* s, a, and b.c are pointers */

today would have to be written using explicit bpf_probe_read() calls as:

  void *t;
  int x;
  bpf_probe_read(&t, sizeof(t), s->a);
  bpf_probe_read(&t, sizeof(t), ((struct b *)t)->b.c);
  bpf_probe_read(&x, sizeof(x), ((struct c *)t)->d);

This is super inconvenient and distracts from program logic a lot. Now, with
added BPF_CORE_READ() macros, you can write the above as:

  int x = BPF_CORE_READ(s, a, b.c, d);

Up to 9 levels of pointer chasing are supported, which should be enough for
any practical purpose, hopefully, without adding too much boilerplate macro
definitions (though there is admittedly some, given how variadic and recursive
C macro have to be implemented).

There is also BPF_CORE_READ_INTO() variant, which relies on caller to allocate
space for result:

  int x;
  BPF_CORE_READ_INTO(&x, s, a, b.c, d);

Result of last bpf_probe_read() call in the chain of calls is the result of
BPF_CORE_READ_INTO(). If any intermediate bpf_probe_read() aall fails, then
all the subsequent ones will fail too, so this is sufficient to know whether
overall "operation" succeeded or not. No short-circuiting of bpf_probe_read()s
is done, though.

BPF_CORE_READ_STR_INTO() is added as well, which differs from
BPF_CORE_READ_INTO() only in that last bpf_probe_read() call (to read final
field after chasing pointers) is replaced with bpf_probe_read_str(). Result of
bpf_probe_read_str() is returned as a result of BPF_CORE_READ_STR_INTO() macro
itself, so that applications can track return code and/or length of read
string.

Patch set outline:
- patch #1 undoes previously added GCC-specific bpf-helpers.h include;
- patch #2 splits off legacy stuff we don't want to carry over;
- patch #3 adjusts CO-RE reloc tests to avoid subsequent naming conflict with
  BPF_CORE_READ;
- patch #4 splits off bpf_tracing.h;
- patch #5 moves bpf_{helpers,endian,tracing}.h into libbpf and adjusts
  Makefiles to include libbpf for header search;
- patch #6 adds variadic BPF_CORE_READ() macro family, as described above;
- patch #7 adds tests to verify all possible levels of pointer nestedness for
  BPF_CORE_READ(), as well as correctness test for BPF_CORE_READ_STR_INTO().

v1->v2:
- fix CO-RE reloc tests before bpf_helpers.h move (Song);
- split off legacy stuff we don't want to carry over (Daniel, Toke);
- split off bpf_tracing.h (Daniel);
- fix samples/bpf build (assuming other fixes are applied);
- switch remaining maps either to bpf_map_def_legacy or BTF-defined maps;

Andrii Nakryiko (7):
  selftests/bpf: undo GCC-specific bpf_helpers.h changes
  selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  libbpf: move bpf_{helpers,endian,tracing}.h into libbpf
  libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers
  selftests/bpf: add BPF_CORE_READ and BPF_CORE_READ_STR_INTO macro
    tests

 samples/bpf/Makefile                          |   2 +-
 samples/bpf/hbm_kern.h                        |  28 +-
 samples/bpf/map_perf_test_kern.c              |  24 +-
 samples/bpf/offwaketime_kern.c                |   1 +
 samples/bpf/parse_ldabs.c                     |   1 +
 samples/bpf/sampleip_kern.c                   |   1 +
 samples/bpf/sockex1_kern.c                    |   1 +
 samples/bpf/sockex2_kern.c                    |   1 +
 samples/bpf/sockex3_kern.c                    |   1 +
 samples/bpf/spintest_kern.c                   |   1 +
 samples/bpf/tcbpf1_kern.c                     |   1 +
 samples/bpf/test_map_in_map_kern.c            |  16 +-
 samples/bpf/test_overhead_kprobe_kern.c       |   1 +
 samples/bpf/test_probe_write_user_kern.c      |   1 +
 samples/bpf/trace_event_kern.c                |   1 +
 samples/bpf/tracex1_kern.c                    |   1 +
 samples/bpf/tracex2_kern.c                    |   1 +
 samples/bpf/tracex3_kern.c                    |   1 +
 samples/bpf/tracex4_kern.c                    |   1 +
 samples/bpf/tracex5_kern.c                    |   1 +
 tools/lib/bpf/Makefile                        |   5 +-
 .../selftests => lib}/bpf/bpf_endian.h        |   0
 .../selftests => lib}/bpf/bpf_helpers.h       | 391 +++++++-----------
 tools/lib/bpf/bpf_tracing.h                   | 195 +++++++++
 tools/testing/selftests/bpf/Makefile          |   2 +-
 tools/testing/selftests/bpf/bpf_legacy.h      |  39 ++
 .../selftests/bpf/prog_tests/core_reloc.c     |   8 +-
 .../selftests/bpf/progs/core_reloc_types.h    |   9 +
 tools/testing/selftests/bpf/progs/loop1.c     |   1 +
 tools/testing/selftests/bpf/progs/loop2.c     |   1 +
 tools/testing/selftests/bpf/progs/loop3.c     |   1 +
 .../testing/selftests/bpf/progs/sockopt_sk.c  |  13 +-
 tools/testing/selftests/bpf/progs/tcp_rtt.c   |  13 +-
 .../selftests/bpf/progs/test_btf_haskv.c      |   1 +
 .../selftests/bpf/progs/test_btf_newkv.c      |   1 +
 .../bpf/progs/test_core_reloc_arrays.c        |  10 +-
 .../bpf/progs/test_core_reloc_flavors.c       |   8 +-
 .../bpf/progs/test_core_reloc_ints.c          |  18 +-
 .../bpf/progs/test_core_reloc_kernel.c        |  60 ++-
 .../bpf/progs/test_core_reloc_misc.c          |   8 +-
 .../bpf/progs/test_core_reloc_mods.c          |  18 +-
 .../bpf/progs/test_core_reloc_nesting.c       |   6 +-
 .../bpf/progs/test_core_reloc_primitives.c    |  12 +-
 .../bpf/progs/test_core_reloc_ptr_as_arr.c    |   4 +-
 44 files changed, 587 insertions(+), 323 deletions(-)
 rename tools/{testing/selftests => lib}/bpf/bpf_endian.h (100%)
 rename tools/{testing/selftests => lib}/bpf/bpf_helpers.h (66%)
 create mode 100644 tools/lib/bpf/bpf_tracing.h
 create mode 100644 tools/testing/selftests/bpf/bpf_legacy.h

-- 
2.17.1


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

* [PATCH v2 bpf-next 1/7] selftests/bpf: undo GCC-specific bpf_helpers.h changes
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Having GCC provide its own bpf-helper.h is not the right approach and is
going to be changed. Undo bpf_helpers.h change before moving
bpf_helpers.h into libbpf.

Acked-by: Song Liu <songliubraving@fb.com>
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 tools/testing/selftests/bpf/bpf_helpers.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 54a50699bbfd..a1d9b97b8e15 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -13,8 +13,6 @@
 			 ##__VA_ARGS__);		\
 })
 
-#ifdef __clang__
-
 /* helper macro to place programs, maps, license in
  * different sections in elf_bpf file. Section names
  * are interpreted by elf_bpf loader
@@ -258,12 +256,6 @@ struct bpf_map_def {
 	unsigned int numa_node;
 };
 
-#else
-
-#include <bpf-helpers.h>
-
-#endif
-
 #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
 	struct ____btf_map_##name {				\
 		type_key key;					\
-- 
2.17.1


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

* [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 1/7] selftests/bpf: undo GCC-specific bpf_helpers.h changes Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
                     ` (2 more replies)
  2019-10-02 21:50 ` [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro Andrii Nakryiko
                   ` (4 subsequent siblings)
  6 siblings, 3 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Split off few legacy things from bpf_helpers.h into separate
bpf_legacy.h file:
- load_{byte|half|word};
- remove extra inner_idx and numa_node fields from bpf_map_def and
  introduce bpf_map_def_legacy for use in samples;
- move BPF_ANNOTATE_KV_PAIR into bpf_legacy.h.

Adjust samples and selftests accordingly by either including
bpf_legacy.h and using bpf_map_def_legacy, or switching to BTF-defined
maps altogether.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 samples/bpf/hbm_kern.h                        | 28 +++++++------
 samples/bpf/map_perf_test_kern.c              | 23 +++++------
 samples/bpf/parse_ldabs.c                     |  1 +
 samples/bpf/sockex1_kern.c                    |  1 +
 samples/bpf/sockex2_kern.c                    |  1 +
 samples/bpf/sockex3_kern.c                    |  1 +
 samples/bpf/tcbpf1_kern.c                     |  1 +
 samples/bpf/test_map_in_map_kern.c            | 15 +++----
 tools/testing/selftests/bpf/bpf_helpers.h     | 24 +-----------
 tools/testing/selftests/bpf/bpf_legacy.h      | 39 +++++++++++++++++++
 .../testing/selftests/bpf/progs/sockopt_sk.c  | 13 +++----
 tools/testing/selftests/bpf/progs/tcp_rtt.c   | 13 +++----
 .../selftests/bpf/progs/test_btf_haskv.c      |  1 +
 .../selftests/bpf/progs/test_btf_newkv.c      |  1 +
 14 files changed, 92 insertions(+), 70 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/bpf_legacy.h

diff --git a/samples/bpf/hbm_kern.h b/samples/bpf/hbm_kern.h
index aa207a2eebbd..91880a0e9c2f 100644
--- a/samples/bpf/hbm_kern.h
+++ b/samples/bpf/hbm_kern.h
@@ -24,6 +24,7 @@
 #include <net/inet_ecn.h>
 #include "bpf_endian.h"
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 #include "hbm.h"
 
 #define DROP_PKT	0
@@ -59,21 +60,18 @@
 #define BYTES_PER_NS(delta, rate) ((((u64)(delta)) * (rate)) >> 20)
 #define BYTES_TO_NS(bytes, rate) div64_u64(((u64)(bytes)) << 20, (u64)(rate))
 
-struct bpf_map_def SEC("maps") queue_state = {
-	.type = BPF_MAP_TYPE_CGROUP_STORAGE,
-	.key_size = sizeof(struct bpf_cgroup_storage_key),
-	.value_size = sizeof(struct hbm_vqueue),
-};
-BPF_ANNOTATE_KV_PAIR(queue_state, struct bpf_cgroup_storage_key,
-		     struct hbm_vqueue);
-
-struct bpf_map_def SEC("maps") queue_stats = {
-	.type = BPF_MAP_TYPE_ARRAY,
-	.key_size = sizeof(u32),
-	.value_size = sizeof(struct hbm_queue_stats),
-	.max_entries = 1,
-};
-BPF_ANNOTATE_KV_PAIR(queue_stats, int, struct hbm_queue_stats);
+struct {
+	__uint(type, BPF_MAP_TYPE_CGROUP_STORAGE);
+	__type(key, struct bpf_cgroup_storage_key);
+	__type(value, struct hbm_vqueue);
+} queue_state SEC(".maps");
+
+struct {
+	__uint(type, BPF_MAP_TYPE_ARRAY);
+	__uint(max_entries, 1);
+	__type(key, u32);
+	__type(value, struct hvm_queue_stats);
+} queue_stats SEC(".maps");
 
 struct hbm_pkt_info {
 	int	cwnd;
diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c
index 2b2ffb97018b..f47ee513cb7c 100644
--- a/samples/bpf/map_perf_test_kern.c
+++ b/samples/bpf/map_perf_test_kern.c
@@ -9,25 +9,26 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 #define MAX_ENTRIES 1000
 #define MAX_NR_CPUS 1024
 
-struct bpf_map_def SEC("maps") hash_map = {
+struct bpf_map_def_legacy SEC("maps") hash_map = {
 	.type = BPF_MAP_TYPE_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
 	.max_entries = MAX_ENTRIES,
 };
 
-struct bpf_map_def SEC("maps") lru_hash_map = {
+struct bpf_map_def_legacy SEC("maps") lru_hash_map = {
 	.type = BPF_MAP_TYPE_LRU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
 	.max_entries = 10000,
 };
 
-struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
+struct bpf_map_def_legacy SEC("maps") nocommon_lru_hash_map = {
 	.type = BPF_MAP_TYPE_LRU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
@@ -35,7 +36,7 @@ struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
 	.map_flags = BPF_F_NO_COMMON_LRU,
 };
 
-struct bpf_map_def SEC("maps") inner_lru_hash_map = {
+struct bpf_map_def_legacy SEC("maps") inner_lru_hash_map = {
 	.type = BPF_MAP_TYPE_LRU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
@@ -44,20 +45,20 @@ struct bpf_map_def SEC("maps") inner_lru_hash_map = {
 	.numa_node = 0,
 };
 
-struct bpf_map_def SEC("maps") array_of_lru_hashs = {
+struct bpf_map_def_legacy SEC("maps") array_of_lru_hashs = {
 	.type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
 	.key_size = sizeof(u32),
 	.max_entries = MAX_NR_CPUS,
 };
 
-struct bpf_map_def SEC("maps") percpu_hash_map = {
+struct bpf_map_def_legacy SEC("maps") percpu_hash_map = {
 	.type = BPF_MAP_TYPE_PERCPU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
 	.max_entries = MAX_ENTRIES,
 };
 
-struct bpf_map_def SEC("maps") hash_map_alloc = {
+struct bpf_map_def_legacy SEC("maps") hash_map_alloc = {
 	.type = BPF_MAP_TYPE_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
@@ -65,7 +66,7 @@ struct bpf_map_def SEC("maps") hash_map_alloc = {
 	.map_flags = BPF_F_NO_PREALLOC,
 };
 
-struct bpf_map_def SEC("maps") percpu_hash_map_alloc = {
+struct bpf_map_def_legacy SEC("maps") percpu_hash_map_alloc = {
 	.type = BPF_MAP_TYPE_PERCPU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
@@ -73,7 +74,7 @@ struct bpf_map_def SEC("maps") percpu_hash_map_alloc = {
 	.map_flags = BPF_F_NO_PREALLOC,
 };
 
-struct bpf_map_def SEC("maps") lpm_trie_map_alloc = {
+struct bpf_map_def_legacy SEC("maps") lpm_trie_map_alloc = {
 	.type = BPF_MAP_TYPE_LPM_TRIE,
 	.key_size = 8,
 	.value_size = sizeof(long),
@@ -81,14 +82,14 @@ struct bpf_map_def SEC("maps") lpm_trie_map_alloc = {
 	.map_flags = BPF_F_NO_PREALLOC,
 };
 
-struct bpf_map_def SEC("maps") array_map = {
+struct bpf_map_def_legacy SEC("maps") array_map = {
 	.type = BPF_MAP_TYPE_ARRAY,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
 	.max_entries = MAX_ENTRIES,
 };
 
-struct bpf_map_def SEC("maps") lru_hash_lookup_map = {
+struct bpf_map_def_legacy SEC("maps") lru_hash_lookup_map = {
 	.type = BPF_MAP_TYPE_LRU_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(long),
diff --git a/samples/bpf/parse_ldabs.c b/samples/bpf/parse_ldabs.c
index 6db6b21fdc6d..ef5892377beb 100644
--- a/samples/bpf/parse_ldabs.c
+++ b/samples/bpf/parse_ldabs.c
@@ -12,6 +12,7 @@
 #include <linux/udp.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 #define DEFAULT_PKTGEN_UDP_PORT	9
 #define IP_MF			0x2000
diff --git a/samples/bpf/sockex1_kern.c b/samples/bpf/sockex1_kern.c
index ed18e9a4909c..f96943f443ab 100644
--- a/samples/bpf/sockex1_kern.c
+++ b/samples/bpf/sockex1_kern.c
@@ -3,6 +3,7 @@
 #include <uapi/linux/if_packet.h>
 #include <uapi/linux/ip.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 struct bpf_map_def SEC("maps") my_map = {
 	.type = BPF_MAP_TYPE_ARRAY,
diff --git a/samples/bpf/sockex2_kern.c b/samples/bpf/sockex2_kern.c
index f2f9dbc021b0..5566fa7d92fa 100644
--- a/samples/bpf/sockex2_kern.c
+++ b/samples/bpf/sockex2_kern.c
@@ -1,5 +1,6 @@
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 #include <uapi/linux/in.h>
 #include <uapi/linux/if.h>
 #include <uapi/linux/if_ether.h>
diff --git a/samples/bpf/sockex3_kern.c b/samples/bpf/sockex3_kern.c
index c527b57d3ec8..151dd842ecc0 100644
--- a/samples/bpf/sockex3_kern.c
+++ b/samples/bpf/sockex3_kern.c
@@ -6,6 +6,7 @@
  */
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 #include <uapi/linux/in.h>
 #include <uapi/linux/if.h>
 #include <uapi/linux/if_ether.h>
diff --git a/samples/bpf/tcbpf1_kern.c b/samples/bpf/tcbpf1_kern.c
index 274c884c87fe..ff43341bdfce 100644
--- a/samples/bpf/tcbpf1_kern.c
+++ b/samples/bpf/tcbpf1_kern.c
@@ -8,6 +8,7 @@
 #include <uapi/linux/filter.h>
 #include <uapi/linux/pkt_cls.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 /* compiler workaround */
 #define _htonl __builtin_bswap32
diff --git a/samples/bpf/test_map_in_map_kern.c b/samples/bpf/test_map_in_map_kern.c
index 42c44d091dd1..8101bf3dc7f7 100644
--- a/samples/bpf/test_map_in_map_kern.c
+++ b/samples/bpf/test_map_in_map_kern.c
@@ -11,11 +11,12 @@
 #include <uapi/linux/bpf.h>
 #include <uapi/linux/in6.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 #define MAX_NR_PORTS 65536
 
 /* map #0 */
-struct bpf_map_def SEC("maps") port_a = {
+struct bpf_map_def_legacy SEC("maps") port_a = {
 	.type = BPF_MAP_TYPE_ARRAY,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(int),
@@ -23,7 +24,7 @@ struct bpf_map_def SEC("maps") port_a = {
 };
 
 /* map #1 */
-struct bpf_map_def SEC("maps") port_h = {
+struct bpf_map_def_legacy SEC("maps") port_h = {
 	.type = BPF_MAP_TYPE_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(int),
@@ -31,7 +32,7 @@ struct bpf_map_def SEC("maps") port_h = {
 };
 
 /* map #2 */
-struct bpf_map_def SEC("maps") reg_result_h = {
+struct bpf_map_def_legacy SEC("maps") reg_result_h = {
 	.type = BPF_MAP_TYPE_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(int),
@@ -39,7 +40,7 @@ struct bpf_map_def SEC("maps") reg_result_h = {
 };
 
 /* map #3 */
-struct bpf_map_def SEC("maps") inline_result_h = {
+struct bpf_map_def_legacy SEC("maps") inline_result_h = {
 	.type = BPF_MAP_TYPE_HASH,
 	.key_size = sizeof(u32),
 	.value_size = sizeof(int),
@@ -47,7 +48,7 @@ struct bpf_map_def SEC("maps") inline_result_h = {
 };
 
 /* map #4 */ /* Test case #0 */
-struct bpf_map_def SEC("maps") a_of_port_a = {
+struct bpf_map_def_legacy SEC("maps") a_of_port_a = {
 	.type = BPF_MAP_TYPE_ARRAY_OF_MAPS,
 	.key_size = sizeof(u32),
 	.inner_map_idx = 0, /* map_fd[0] is port_a */
@@ -55,7 +56,7 @@ struct bpf_map_def SEC("maps") a_of_port_a = {
 };
 
 /* map #5 */ /* Test case #1 */
-struct bpf_map_def SEC("maps") h_of_port_a = {
+struct bpf_map_def_legacy SEC("maps") h_of_port_a = {
 	.type = BPF_MAP_TYPE_HASH_OF_MAPS,
 	.key_size = sizeof(u32),
 	.inner_map_idx = 0, /* map_fd[0] is port_a */
@@ -63,7 +64,7 @@ struct bpf_map_def SEC("maps") h_of_port_a = {
 };
 
 /* map #6 */ /* Test case #2 */
-struct bpf_map_def SEC("maps") h_of_port_h = {
+struct bpf_map_def_legacy SEC("maps") h_of_port_h = {
 	.type = BPF_MAP_TYPE_HASH_OF_MAPS,
 	.key_size = sizeof(u32),
 	.inner_map_idx = 1, /* map_fd[1] is port_h */
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index a1d9b97b8e15..7b75c38238e4 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -232,19 +232,8 @@ static long long (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *ip,
 					  int ip_len, void *tcp, int tcp_len) =
 	(void *) BPF_FUNC_tcp_gen_syncookie;
 
-/* llvm builtin functions that eBPF C program may use to
- * emit BPF_LD_ABS and BPF_LD_IND instructions
- */
-struct sk_buff;
-unsigned long long load_byte(void *skb,
-			     unsigned long long off) asm("llvm.bpf.load.byte");
-unsigned long long load_half(void *skb,
-			     unsigned long long off) asm("llvm.bpf.load.half");
-unsigned long long load_word(void *skb,
-			     unsigned long long off) asm("llvm.bpf.load.word");
-
 /* a helper structure used by eBPF C program
- * to describe map attributes to elf_bpf loader
+ * to describe BPF map attributes to libbpf loader
  */
 struct bpf_map_def {
 	unsigned int type;
@@ -252,19 +241,8 @@ struct bpf_map_def {
 	unsigned int value_size;
 	unsigned int max_entries;
 	unsigned int map_flags;
-	unsigned int inner_map_idx;
-	unsigned int numa_node;
 };
 
-#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
-	struct ____btf_map_##name {				\
-		type_key key;					\
-		type_val value;					\
-	};							\
-	struct ____btf_map_##name				\
-	__attribute__ ((section(".maps." #name), used))		\
-		____btf_map_##name = { }
-
 static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =
 	(void *) BPF_FUNC_skb_load_bytes;
 static int (*bpf_skb_load_bytes_relative)(void *ctx, int off, void *to, int len, __u32 start_header) =
diff --git a/tools/testing/selftests/bpf/bpf_legacy.h b/tools/testing/selftests/bpf/bpf_legacy.h
new file mode 100644
index 000000000000..6f8988738bc1
--- /dev/null
+++ b/tools/testing/selftests/bpf/bpf_legacy.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+#ifndef __BPF_LEGACY__
+#define __BPF_LEGACY__
+
+/*
+ * legacy bpf_map_def with extra fields supported only by bpf_load(), do not
+ * use outside of samples/bpf
+ */
+struct bpf_map_def_legacy {
+	unsigned int type;
+	unsigned int key_size;
+	unsigned int value_size;
+	unsigned int max_entries;
+	unsigned int map_flags;
+	unsigned int inner_map_idx;
+	unsigned int numa_node;
+};
+
+#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val)		\
+	struct ____btf_map_##name {				\
+		type_key key;					\
+		type_val value;					\
+	};							\
+	struct ____btf_map_##name				\
+	__attribute__ ((section(".maps." #name), used))		\
+		____btf_map_##name = { }
+
+/* llvm builtin functions that eBPF C program may use to
+ * emit BPF_LD_ABS and BPF_LD_IND instructions
+ */
+unsigned long long load_byte(void *skb,
+			     unsigned long long off) asm("llvm.bpf.load.byte");
+unsigned long long load_half(void *skb,
+			     unsigned long long off) asm("llvm.bpf.load.half");
+unsigned long long load_word(void *skb,
+			     unsigned long long off) asm("llvm.bpf.load.word");
+
+#endif
+
diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c
index 9a3d1c79e6fe..1bafbb944e37 100644
--- a/tools/testing/selftests/bpf/progs/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c
@@ -14,13 +14,12 @@ struct sockopt_sk {
 	__u8 val;
 };
 
-struct bpf_map_def SEC("maps") socket_storage_map = {
-	.type = BPF_MAP_TYPE_SK_STORAGE,
-	.key_size = sizeof(int),
-	.value_size = sizeof(struct sockopt_sk),
-	.map_flags = BPF_F_NO_PREALLOC,
-};
-BPF_ANNOTATE_KV_PAIR(socket_storage_map, int, struct sockopt_sk);
+struct {
+	__uint(type, BPF_MAP_TYPE_SK_STORAGE);
+	__uint(map_flags, BPF_F_NO_PREALLOC);
+	__type(key, int);
+	__type(value, struct sockopt_sk);
+} socket_storage_map SEC(".maps");
 
 SEC("cgroup/getsockopt")
 int _getsockopt(struct bpf_sockopt *ctx)
diff --git a/tools/testing/selftests/bpf/progs/tcp_rtt.c b/tools/testing/selftests/bpf/progs/tcp_rtt.c
index 233bdcb1659e..2cf813a06b83 100644
--- a/tools/testing/selftests/bpf/progs/tcp_rtt.c
+++ b/tools/testing/selftests/bpf/progs/tcp_rtt.c
@@ -13,13 +13,12 @@ struct tcp_rtt_storage {
 	__u32 icsk_retransmits;
 };
 
-struct bpf_map_def SEC("maps") socket_storage_map = {
-	.type = BPF_MAP_TYPE_SK_STORAGE,
-	.key_size = sizeof(int),
-	.value_size = sizeof(struct tcp_rtt_storage),
-	.map_flags = BPF_F_NO_PREALLOC,
-};
-BPF_ANNOTATE_KV_PAIR(socket_storage_map, int, struct tcp_rtt_storage);
+struct {
+	__uint(type, BPF_MAP_TYPE_SK_STORAGE);
+	__uint(map_flags, BPF_F_NO_PREALLOC);
+	__type(key, int);
+	__type(value, struct tcp_rtt_storage);
+} socket_storage_map SEC(".maps");
 
 SEC("sockops")
 int _sockops(struct bpf_sock_ops *ctx)
diff --git a/tools/testing/selftests/bpf/progs/test_btf_haskv.c b/tools/testing/selftests/bpf/progs/test_btf_haskv.c
index e5c79fe0ffdb..763c51447c19 100644
--- a/tools/testing/selftests/bpf/progs/test_btf_haskv.c
+++ b/tools/testing/selftests/bpf/progs/test_btf_haskv.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2018 Facebook */
 #include <linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 int _version SEC("version") = 1;
 
diff --git a/tools/testing/selftests/bpf/progs/test_btf_newkv.c b/tools/testing/selftests/bpf/progs/test_btf_newkv.c
index 5ee3622ddebb..96f9e8451029 100644
--- a/tools/testing/selftests/bpf/progs/test_btf_newkv.c
+++ b/tools/testing/selftests/bpf/progs/test_btf_newkv.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2018 Facebook */
 #include <linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_legacy.h"
 
 int _version SEC("version") = 1;
 
-- 
2.17.1


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

* [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 1/7] selftests/bpf: undo GCC-specific bpf_helpers.h changes Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-03 20:16   ` Song Liu
  2019-10-02 21:50 ` [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h Andrii Nakryiko
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

To allow adding a variadic BPF_CORE_READ macro with slightly different
syntax and semantics, define CORE_READ in CO-RE reloc tests, which is
a thin wrapper around low-level bpf_core_read() macro, which in turn is
just a wrapper around bpf_probe_read().

Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 tools/testing/selftests/bpf/bpf_helpers.h      |  8 ++++----
 .../bpf/progs/test_core_reloc_arrays.c         | 10 ++++++----
 .../bpf/progs/test_core_reloc_flavors.c        |  8 +++++---
 .../selftests/bpf/progs/test_core_reloc_ints.c | 18 ++++++++++--------
 .../bpf/progs/test_core_reloc_kernel.c         |  6 ++++--
 .../selftests/bpf/progs/test_core_reloc_misc.c |  8 +++++---
 .../selftests/bpf/progs/test_core_reloc_mods.c | 18 ++++++++++--------
 .../bpf/progs/test_core_reloc_nesting.c        |  6 ++++--
 .../bpf/progs/test_core_reloc_primitives.c     | 12 +++++++-----
 .../bpf/progs/test_core_reloc_ptr_as_arr.c     |  4 +++-
 10 files changed, 58 insertions(+), 40 deletions(-)

diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 7b75c38238e4..5210cc7d7c5c 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -483,7 +483,7 @@ struct pt_regs;
 #endif
 
 /*
- * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset
+ * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
  * relocation for source address using __builtin_preserve_access_index()
  * built-in, provided by Clang.
  *
@@ -498,8 +498,8 @@ struct pt_regs;
  * actual field offset, based on target kernel BTF type that matches original
  * (local) BTF, used to record relocation.
  */
-#define BPF_CORE_READ(dst, src)						\
-	bpf_probe_read((dst), sizeof(*(src)),				\
-		       __builtin_preserve_access_index(src))
+#define bpf_core_read(dst, sz, src)					    \
+	bpf_probe_read(dst, sz,						    \
+		       (const void *)__builtin_preserve_access_index(src))
 
 #endif
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
index bf67f0fdf743..58efe4944594 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
@@ -31,6 +31,8 @@ struct core_reloc_arrays {
 	struct core_reloc_arrays_substruct d[1][2];
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_arrays(void *ctx)
 {
@@ -38,16 +40,16 @@ int test_core_arrays(void *ctx)
 	struct core_reloc_arrays_output *out = (void *)&data.out;
 
 	/* in->a[2] */
-	if (BPF_CORE_READ(&out->a2, &in->a[2]))
+	if (CORE_READ(&out->a2, &in->a[2]))
 		return 1;
 	/* in->b[1][2][3] */
-	if (BPF_CORE_READ(&out->b123, &in->b[1][2][3]))
+	if (CORE_READ(&out->b123, &in->b[1][2][3]))
 		return 1;
 	/* in->c[1].c */
-	if (BPF_CORE_READ(&out->c1c, &in->c[1].c))
+	if (CORE_READ(&out->c1c, &in->c[1].c))
 		return 1;
 	/* in->d[0][0].d */
-	if (BPF_CORE_READ(&out->d00d, &in->d[0][0].d))
+	if (CORE_READ(&out->d00d, &in->d[0][0].d))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
index 9fda73e87972..3348acc7e50b 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
@@ -39,6 +39,8 @@ struct core_reloc_flavors___weird {
 	};
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_flavors(void *ctx)
 {
@@ -48,13 +50,13 @@ int test_core_flavors(void *ctx)
 	struct core_reloc_flavors *out = (void *)&data.out;
 
 	/* read a using weird layout */
-	if (BPF_CORE_READ(&out->a, &in_weird->a))
+	if (CORE_READ(&out->a, &in_weird->a))
 		return 1;
 	/* read b using reversed layout */
-	if (BPF_CORE_READ(&out->b, &in_rev->b))
+	if (CORE_READ(&out->b, &in_rev->b))
 		return 1;
 	/* read c using original layout */
-	if (BPF_CORE_READ(&out->c, &in_orig->c))
+	if (CORE_READ(&out->c, &in_orig->c))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
index d99233c8008a..cfe16ede48dd 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
@@ -23,20 +23,22 @@ struct core_reloc_ints {
 	int64_t		s64_field;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_ints(void *ctx)
 {
 	struct core_reloc_ints *in = (void *)&data.in;
 	struct core_reloc_ints *out = (void *)&data.out;
 
-	if (BPF_CORE_READ(&out->u8_field, &in->u8_field) ||
-	    BPF_CORE_READ(&out->s8_field, &in->s8_field) ||
-	    BPF_CORE_READ(&out->u16_field, &in->u16_field) ||
-	    BPF_CORE_READ(&out->s16_field, &in->s16_field) ||
-	    BPF_CORE_READ(&out->u32_field, &in->u32_field) ||
-	    BPF_CORE_READ(&out->s32_field, &in->s32_field) ||
-	    BPF_CORE_READ(&out->u64_field, &in->u64_field) ||
-	    BPF_CORE_READ(&out->s64_field, &in->s64_field))
+	if (CORE_READ(&out->u8_field, &in->u8_field) ||
+	    CORE_READ(&out->s8_field, &in->s8_field) ||
+	    CORE_READ(&out->u16_field, &in->u16_field) ||
+	    CORE_READ(&out->s16_field, &in->s16_field) ||
+	    CORE_READ(&out->u32_field, &in->u32_field) ||
+	    CORE_READ(&out->s32_field, &in->s32_field) ||
+	    CORE_READ(&out->u64_field, &in->u64_field) ||
+	    CORE_READ(&out->s64_field, &in->s64_field))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
index 37e02aa3f0c8..e5308026cfda 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
@@ -17,6 +17,8 @@ struct task_struct {
 	int tgid;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_kernel(void *ctx)
 {
@@ -24,8 +26,8 @@ int test_core_kernel(void *ctx)
 	uint64_t pid_tgid = bpf_get_current_pid_tgid();
 	int pid, tgid;
 
-	if (BPF_CORE_READ(&pid, &task->pid) ||
-	    BPF_CORE_READ(&tgid, &task->tgid))
+	if (CORE_READ(&pid, &task->pid) ||
+	    CORE_READ(&tgid, &task->tgid))
 		return 1;
 
 	/* validate pid + tgid matches */
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c
index c59984bd3e23..40c4638ab5cc 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_misc.c
@@ -32,6 +32,8 @@ struct core_reloc_misc_extensible {
 	int b;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_misc(void *ctx)
 {
@@ -41,15 +43,15 @@ int test_core_misc(void *ctx)
 	struct core_reloc_misc_output *out = (void *)&data.out;
 
 	/* record two different relocations with the same accessor string */
-	if (BPF_CORE_READ(&out->a, &in_a->a1) ||	/* accessor: 0:0 */
-	    BPF_CORE_READ(&out->b, &in_b->b1))		/* accessor: 0:0 */
+	if (CORE_READ(&out->a, &in_a->a1) ||		/* accessor: 0:0 */
+	    CORE_READ(&out->b, &in_b->b1))		/* accessor: 0:0 */
 		return 1;
 
 	/* Validate relocations capture array-only accesses for structs with
 	 * fixed header, but with potentially extendable tail. This will read
 	 * first 4 bytes of 2nd element of in_ext array of potentially
 	 * variably sized struct core_reloc_misc_extensible. */ 
-	if (BPF_CORE_READ(&out->c, &in_ext[2]))		/* accessor: 2 */
+	if (CORE_READ(&out->c, &in_ext[2]))		/* accessor: 2 */
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c
index f98b942c062b..99fc9ee21895 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_mods.c
@@ -41,20 +41,22 @@ struct core_reloc_mods {
 	core_reloc_mods_substruct_t h;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_mods(void *ctx)
 {
 	struct core_reloc_mods *in = (void *)&data.in;
 	struct core_reloc_mods_output *out = (void *)&data.out;
 
-	if (BPF_CORE_READ(&out->a, &in->a) ||
-	    BPF_CORE_READ(&out->b, &in->b) ||
-	    BPF_CORE_READ(&out->c, &in->c) ||
-	    BPF_CORE_READ(&out->d, &in->d) ||
-	    BPF_CORE_READ(&out->e, &in->e[2]) ||
-	    BPF_CORE_READ(&out->f, &in->f[1]) ||
-	    BPF_CORE_READ(&out->g, &in->g.x) ||
-	    BPF_CORE_READ(&out->h, &in->h.y))
+	if (CORE_READ(&out->a, &in->a) ||
+	    CORE_READ(&out->b, &in->b) ||
+	    CORE_READ(&out->c, &in->c) ||
+	    CORE_READ(&out->d, &in->d) ||
+	    CORE_READ(&out->e, &in->e[2]) ||
+	    CORE_READ(&out->f, &in->f[1]) ||
+	    CORE_READ(&out->g, &in->g.x) ||
+	    CORE_READ(&out->h, &in->h.y))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c
index 3ca30cec2b39..c84fff3bdd72 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_nesting.c
@@ -30,15 +30,17 @@ struct core_reloc_nesting {
 	} b;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_nesting(void *ctx)
 {
 	struct core_reloc_nesting *in = (void *)&data.in;
 	struct core_reloc_nesting *out = (void *)&data.out;
 
-	if (BPF_CORE_READ(&out->a.a.a, &in->a.a.a))
+	if (CORE_READ(&out->a.a.a, &in->a.a.a))
 		return 1;
-	if (BPF_CORE_READ(&out->b.b.b, &in->b.b.b))
+	if (CORE_READ(&out->b.b.b, &in->b.b.b))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c
index add52f23ab35..4038e9907162 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_primitives.c
@@ -25,17 +25,19 @@ struct core_reloc_primitives {
 	int (*f)(const char *);
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_primitives(void *ctx)
 {
 	struct core_reloc_primitives *in = (void *)&data.in;
 	struct core_reloc_primitives *out = (void *)&data.out;
 
-	if (BPF_CORE_READ(&out->a, &in->a) ||
-	    BPF_CORE_READ(&out->b, &in->b) ||
-	    BPF_CORE_READ(&out->c, &in->c) ||
-	    BPF_CORE_READ(&out->d, &in->d) ||
-	    BPF_CORE_READ(&out->f, &in->f))
+	if (CORE_READ(&out->a, &in->a) ||
+	    CORE_READ(&out->b, &in->b) ||
+	    CORE_READ(&out->c, &in->c) ||
+	    CORE_READ(&out->d, &in->d) ||
+	    CORE_READ(&out->f, &in->f))
 		return 1;
 
 	return 0;
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c
index 526b7ddc7ea1..414d44620258 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ptr_as_arr.c
@@ -16,13 +16,15 @@ struct core_reloc_ptr_as_arr {
 	int a;
 };
 
+#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
+
 SEC("raw_tracepoint/sys_enter")
 int test_core_ptr_as_arr(void *ctx)
 {
 	struct core_reloc_ptr_as_arr *in = (void *)&data.in;
 	struct core_reloc_ptr_as_arr *out = (void *)&data.out;
 
-	if (BPF_CORE_READ(&out->a, &in[2].a))
+	if (CORE_READ(&out->a, &in[2].a))
 		return 1;
 
 	return 0;
-- 
2.17.1


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

* [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
                   ` (2 preceding siblings ...)
  2019-10-02 21:50 ` [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
  2019-10-03 17:33   ` John Fastabend
  2019-10-02 21:50 ` [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf Andrii Nakryiko
                   ` (2 subsequent siblings)
  6 siblings, 2 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Split-off PT_REGS-related helpers into bpf_tracing.h header. Adjust
selftests and samples to include it where necessary.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 samples/bpf/map_perf_test_kern.c          |   1 +
 samples/bpf/offwaketime_kern.c            |   1 +
 samples/bpf/sampleip_kern.c               |   1 +
 samples/bpf/spintest_kern.c               |   1 +
 samples/bpf/test_map_in_map_kern.c        |   1 +
 samples/bpf/test_overhead_kprobe_kern.c   |   1 +
 samples/bpf/test_probe_write_user_kern.c  |   1 +
 samples/bpf/trace_event_kern.c            |   1 +
 samples/bpf/tracex1_kern.c                |   1 +
 samples/bpf/tracex2_kern.c                |   1 +
 samples/bpf/tracex3_kern.c                |   1 +
 samples/bpf/tracex4_kern.c                |   1 +
 samples/bpf/tracex5_kern.c                |   1 +
 tools/testing/selftests/bpf/bpf_helpers.h | 210 ++--------------------
 tools/testing/selftests/bpf/bpf_tracing.h | 195 ++++++++++++++++++++
 tools/testing/selftests/bpf/progs/loop1.c |   1 +
 tools/testing/selftests/bpf/progs/loop2.c |   1 +
 tools/testing/selftests/bpf/progs/loop3.c |   1 +
 18 files changed, 221 insertions(+), 200 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/bpf_tracing.h

diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c
index f47ee513cb7c..5c11aefbc489 100644
--- a/samples/bpf/map_perf_test_kern.c
+++ b/samples/bpf/map_perf_test_kern.c
@@ -10,6 +10,7 @@
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
 #include "bpf_legacy.h"
+#include "bpf_tracing.h"
 
 #define MAX_ENTRIES 1000
 #define MAX_NR_CPUS 1024
diff --git a/samples/bpf/offwaketime_kern.c b/samples/bpf/offwaketime_kern.c
index e7d9a0a3d45b..9cb5207a692f 100644
--- a/samples/bpf/offwaketime_kern.c
+++ b/samples/bpf/offwaketime_kern.c
@@ -6,6 +6,7 @@
  */
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 #include <uapi/linux/ptrace.h>
 #include <uapi/linux/perf_event.h>
 #include <linux/version.h>
diff --git a/samples/bpf/sampleip_kern.c b/samples/bpf/sampleip_kern.c
index ceabf31079cf..4a190893894f 100644
--- a/samples/bpf/sampleip_kern.c
+++ b/samples/bpf/sampleip_kern.c
@@ -9,6 +9,7 @@
 #include <uapi/linux/bpf.h>
 #include <uapi/linux/bpf_perf_event.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 #define MAX_IPS		8192
 
diff --git a/samples/bpf/spintest_kern.c b/samples/bpf/spintest_kern.c
index ce0167d09cdc..6e9478aa2938 100644
--- a/samples/bpf/spintest_kern.c
+++ b/samples/bpf/spintest_kern.c
@@ -10,6 +10,7 @@
 #include <uapi/linux/bpf.h>
 #include <uapi/linux/perf_event.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct bpf_map_def SEC("maps") my_map = {
 	.type = BPF_MAP_TYPE_HASH,
diff --git a/samples/bpf/test_map_in_map_kern.c b/samples/bpf/test_map_in_map_kern.c
index 8101bf3dc7f7..4f80cbe74c72 100644
--- a/samples/bpf/test_map_in_map_kern.c
+++ b/samples/bpf/test_map_in_map_kern.c
@@ -12,6 +12,7 @@
 #include <uapi/linux/in6.h>
 #include "bpf_helpers.h"
 #include "bpf_legacy.h"
+#include "bpf_tracing.h"
 
 #define MAX_NR_PORTS 65536
 
diff --git a/samples/bpf/test_overhead_kprobe_kern.c b/samples/bpf/test_overhead_kprobe_kern.c
index 468a66a92ef9..8d2518e68db9 100644
--- a/samples/bpf/test_overhead_kprobe_kern.c
+++ b/samples/bpf/test_overhead_kprobe_kern.c
@@ -8,6 +8,7 @@
 #include <linux/ptrace.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 #define _(P) ({typeof(P) val = 0; bpf_probe_read(&val, sizeof(val), &P); val;})
 
diff --git a/samples/bpf/test_probe_write_user_kern.c b/samples/bpf/test_probe_write_user_kern.c
index 3a677c807044..a543358218e6 100644
--- a/samples/bpf/test_probe_write_user_kern.c
+++ b/samples/bpf/test_probe_write_user_kern.c
@@ -9,6 +9,7 @@
 #include <uapi/linux/bpf.h>
 #include <linux/version.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct bpf_map_def SEC("maps") dnat_map = {
 	.type = BPF_MAP_TYPE_HASH,
diff --git a/samples/bpf/trace_event_kern.c b/samples/bpf/trace_event_kern.c
index 7068fbdde951..8dc18d233a27 100644
--- a/samples/bpf/trace_event_kern.c
+++ b/samples/bpf/trace_event_kern.c
@@ -10,6 +10,7 @@
 #include <uapi/linux/bpf_perf_event.h>
 #include <uapi/linux/perf_event.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct key_t {
 	char comm[TASK_COMM_LEN];
diff --git a/samples/bpf/tracex1_kern.c b/samples/bpf/tracex1_kern.c
index 107da148820f..1a15f6605129 100644
--- a/samples/bpf/tracex1_kern.c
+++ b/samples/bpf/tracex1_kern.c
@@ -9,6 +9,7 @@
 #include <uapi/linux/bpf.h>
 #include <linux/version.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 #define _(P) ({typeof(P) val = 0; bpf_probe_read(&val, sizeof(val), &P); val;})
 
diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c
index 5e11c20ce5ec..d70b3ea79ea7 100644
--- a/samples/bpf/tracex2_kern.c
+++ b/samples/bpf/tracex2_kern.c
@@ -9,6 +9,7 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct bpf_map_def SEC("maps") my_map = {
 	.type = BPF_MAP_TYPE_HASH,
diff --git a/samples/bpf/tracex3_kern.c b/samples/bpf/tracex3_kern.c
index ea1d4c19c132..9af546bebfa9 100644
--- a/samples/bpf/tracex3_kern.c
+++ b/samples/bpf/tracex3_kern.c
@@ -9,6 +9,7 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct bpf_map_def SEC("maps") my_map = {
 	.type = BPF_MAP_TYPE_HASH,
diff --git a/samples/bpf/tracex4_kern.c b/samples/bpf/tracex4_kern.c
index 6dd8e384de96..2a02cbe9d9a1 100644
--- a/samples/bpf/tracex4_kern.c
+++ b/samples/bpf/tracex4_kern.c
@@ -8,6 +8,7 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 struct pair {
 	u64 val;
diff --git a/samples/bpf/tracex5_kern.c b/samples/bpf/tracex5_kern.c
index 35cb0eed3be5..b3557b21a8fe 100644
--- a/samples/bpf/tracex5_kern.c
+++ b/samples/bpf/tracex5_kern.c
@@ -11,6 +11,7 @@
 #include <uapi/linux/unistd.h>
 #include "syscall_nrs.h"
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 #define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F
 
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 5210cc7d7c5c..cb9d4d2224af 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -232,17 +232,6 @@ static long long (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *ip,
 					  int ip_len, void *tcp, int tcp_len) =
 	(void *) BPF_FUNC_tcp_gen_syncookie;
 
-/* a helper structure used by eBPF C program
- * to describe BPF map attributes to libbpf loader
- */
-struct bpf_map_def {
-	unsigned int type;
-	unsigned int key_size;
-	unsigned int value_size;
-	unsigned int max_entries;
-	unsigned int map_flags;
-};
-
 static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =
 	(void *) BPF_FUNC_skb_load_bytes;
 static int (*bpf_skb_load_bytes_relative)(void *ctx, int off, void *to, int len, __u32 start_header) =
@@ -292,195 +281,16 @@ static int (*bpf_skb_adjust_room)(void *ctx, __s32 len_diff, __u32 mode,
 				  unsigned long long flags) =
 	(void *) BPF_FUNC_skb_adjust_room;
 
-/* Scan the ARCH passed in from ARCH env variable (see Makefile) */
-#if defined(__TARGET_ARCH_x86)
-	#define bpf_target_x86
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_s390)
-	#define bpf_target_s390
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_arm)
-	#define bpf_target_arm
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_arm64)
-	#define bpf_target_arm64
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_mips)
-	#define bpf_target_mips
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_powerpc)
-	#define bpf_target_powerpc
-	#define bpf_target_defined
-#elif defined(__TARGET_ARCH_sparc)
-	#define bpf_target_sparc
-	#define bpf_target_defined
-#else
-	#undef bpf_target_defined
-#endif
-
-/* Fall back to what the compiler says */
-#ifndef bpf_target_defined
-#if defined(__x86_64__)
-	#define bpf_target_x86
-#elif defined(__s390__)
-	#define bpf_target_s390
-#elif defined(__arm__)
-	#define bpf_target_arm
-#elif defined(__aarch64__)
-	#define bpf_target_arm64
-#elif defined(__mips__)
-	#define bpf_target_mips
-#elif defined(__powerpc__)
-	#define bpf_target_powerpc
-#elif defined(__sparc__)
-	#define bpf_target_sparc
-#endif
-#endif
-
-#if defined(bpf_target_x86)
-
-#ifdef __KERNEL__
-#define PT_REGS_PARM1(x) ((x)->di)
-#define PT_REGS_PARM2(x) ((x)->si)
-#define PT_REGS_PARM3(x) ((x)->dx)
-#define PT_REGS_PARM4(x) ((x)->cx)
-#define PT_REGS_PARM5(x) ((x)->r8)
-#define PT_REGS_RET(x) ((x)->sp)
-#define PT_REGS_FP(x) ((x)->bp)
-#define PT_REGS_RC(x) ((x)->ax)
-#define PT_REGS_SP(x) ((x)->sp)
-#define PT_REGS_IP(x) ((x)->ip)
-#else
-#ifdef __i386__
-/* i386 kernel is built with -mregparm=3 */
-#define PT_REGS_PARM1(x) ((x)->eax)
-#define PT_REGS_PARM2(x) ((x)->edx)
-#define PT_REGS_PARM3(x) ((x)->ecx)
-#define PT_REGS_PARM4(x) 0
-#define PT_REGS_PARM5(x) 0
-#define PT_REGS_RET(x) ((x)->esp)
-#define PT_REGS_FP(x) ((x)->ebp)
-#define PT_REGS_RC(x) ((x)->eax)
-#define PT_REGS_SP(x) ((x)->esp)
-#define PT_REGS_IP(x) ((x)->eip)
-#else
-#define PT_REGS_PARM1(x) ((x)->rdi)
-#define PT_REGS_PARM2(x) ((x)->rsi)
-#define PT_REGS_PARM3(x) ((x)->rdx)
-#define PT_REGS_PARM4(x) ((x)->rcx)
-#define PT_REGS_PARM5(x) ((x)->r8)
-#define PT_REGS_RET(x) ((x)->rsp)
-#define PT_REGS_FP(x) ((x)->rbp)
-#define PT_REGS_RC(x) ((x)->rax)
-#define PT_REGS_SP(x) ((x)->rsp)
-#define PT_REGS_IP(x) ((x)->rip)
-#endif
-#endif
-
-#elif defined(bpf_target_s390)
-
-/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
-struct pt_regs;
-#define PT_REGS_S390 const volatile user_pt_regs
-#define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2])
-#define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3])
-#define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4])
-#define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5])
-#define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6])
-#define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14])
-/* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11])
-#define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2])
-#define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15])
-#define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr)
-
-#elif defined(bpf_target_arm)
-
-#define PT_REGS_PARM1(x) ((x)->uregs[0])
-#define PT_REGS_PARM2(x) ((x)->uregs[1])
-#define PT_REGS_PARM3(x) ((x)->uregs[2])
-#define PT_REGS_PARM4(x) ((x)->uregs[3])
-#define PT_REGS_PARM5(x) ((x)->uregs[4])
-#define PT_REGS_RET(x) ((x)->uregs[14])
-#define PT_REGS_FP(x) ((x)->uregs[11]) /* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_RC(x) ((x)->uregs[0])
-#define PT_REGS_SP(x) ((x)->uregs[13])
-#define PT_REGS_IP(x) ((x)->uregs[12])
-
-#elif defined(bpf_target_arm64)
-
-/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
-struct pt_regs;
-#define PT_REGS_ARM64 const volatile struct user_pt_regs
-#define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0])
-#define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1])
-#define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2])
-#define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3])
-#define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4])
-#define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30])
-/* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29])
-#define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0])
-#define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
-#define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc)
-
-#elif defined(bpf_target_mips)
-
-#define PT_REGS_PARM1(x) ((x)->regs[4])
-#define PT_REGS_PARM2(x) ((x)->regs[5])
-#define PT_REGS_PARM3(x) ((x)->regs[6])
-#define PT_REGS_PARM4(x) ((x)->regs[7])
-#define PT_REGS_PARM5(x) ((x)->regs[8])
-#define PT_REGS_RET(x) ((x)->regs[31])
-#define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */
-#define PT_REGS_RC(x) ((x)->regs[1])
-#define PT_REGS_SP(x) ((x)->regs[29])
-#define PT_REGS_IP(x) ((x)->cp0_epc)
-
-#elif defined(bpf_target_powerpc)
-
-#define PT_REGS_PARM1(x) ((x)->gpr[3])
-#define PT_REGS_PARM2(x) ((x)->gpr[4])
-#define PT_REGS_PARM3(x) ((x)->gpr[5])
-#define PT_REGS_PARM4(x) ((x)->gpr[6])
-#define PT_REGS_PARM5(x) ((x)->gpr[7])
-#define PT_REGS_RC(x) ((x)->gpr[3])
-#define PT_REGS_SP(x) ((x)->sp)
-#define PT_REGS_IP(x) ((x)->nip)
-
-#elif defined(bpf_target_sparc)
-
-#define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0])
-#define PT_REGS_PARM2(x) ((x)->u_regs[UREG_I1])
-#define PT_REGS_PARM3(x) ((x)->u_regs[UREG_I2])
-#define PT_REGS_PARM4(x) ((x)->u_regs[UREG_I3])
-#define PT_REGS_PARM5(x) ((x)->u_regs[UREG_I4])
-#define PT_REGS_RET(x) ((x)->u_regs[UREG_I7])
-#define PT_REGS_RC(x) ((x)->u_regs[UREG_I0])
-#define PT_REGS_SP(x) ((x)->u_regs[UREG_FP])
-
-/* Should this also be a bpf_target check for the sparc case? */
-#if defined(__arch64__)
-#define PT_REGS_IP(x) ((x)->tpc)
-#else
-#define PT_REGS_IP(x) ((x)->pc)
-#endif
-
-#endif
-
-#if defined(bpf_target_powerpc)
-#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = (ctx)->link; })
-#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
-#elif defined(bpf_target_sparc)
-#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = PT_REGS_RET(ctx); })
-#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
-#else
-#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({				\
-		bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
-#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)	({				\
-		bpf_probe_read(&(ip), sizeof(ip),				\
-				(void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
-#endif
+/* a helper structure used by eBPF C program
+ * to describe BPF map attributes to libbpf loader
+ */
+struct bpf_map_def {
+	unsigned int type;
+	unsigned int key_size;
+	unsigned int value_size;
+	unsigned int max_entries;
+	unsigned int map_flags;
+};
 
 /*
  * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
diff --git a/tools/testing/selftests/bpf/bpf_tracing.h b/tools/testing/selftests/bpf/bpf_tracing.h
new file mode 100644
index 000000000000..b0dafe8b4ebc
--- /dev/null
+++ b/tools/testing/selftests/bpf/bpf_tracing.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
+#ifndef __BPF_TRACING_H__
+#define __BPF_TRACING_H__
+
+/* Scan the ARCH passed in from ARCH env variable (see Makefile) */
+#if defined(__TARGET_ARCH_x86)
+	#define bpf_target_x86
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_s390)
+	#define bpf_target_s390
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_arm)
+	#define bpf_target_arm
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_arm64)
+	#define bpf_target_arm64
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_mips)
+	#define bpf_target_mips
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_powerpc)
+	#define bpf_target_powerpc
+	#define bpf_target_defined
+#elif defined(__TARGET_ARCH_sparc)
+	#define bpf_target_sparc
+	#define bpf_target_defined
+#else
+	#undef bpf_target_defined
+#endif
+
+/* Fall back to what the compiler says */
+#ifndef bpf_target_defined
+#if defined(__x86_64__)
+	#define bpf_target_x86
+#elif defined(__s390__)
+	#define bpf_target_s390
+#elif defined(__arm__)
+	#define bpf_target_arm
+#elif defined(__aarch64__)
+	#define bpf_target_arm64
+#elif defined(__mips__)
+	#define bpf_target_mips
+#elif defined(__powerpc__)
+	#define bpf_target_powerpc
+#elif defined(__sparc__)
+	#define bpf_target_sparc
+#endif
+#endif
+
+#if defined(bpf_target_x86)
+
+#ifdef __KERNEL__
+#define PT_REGS_PARM1(x) ((x)->di)
+#define PT_REGS_PARM2(x) ((x)->si)
+#define PT_REGS_PARM3(x) ((x)->dx)
+#define PT_REGS_PARM4(x) ((x)->cx)
+#define PT_REGS_PARM5(x) ((x)->r8)
+#define PT_REGS_RET(x) ((x)->sp)
+#define PT_REGS_FP(x) ((x)->bp)
+#define PT_REGS_RC(x) ((x)->ax)
+#define PT_REGS_SP(x) ((x)->sp)
+#define PT_REGS_IP(x) ((x)->ip)
+#else
+#ifdef __i386__
+/* i386 kernel is built with -mregparm=3 */
+#define PT_REGS_PARM1(x) ((x)->eax)
+#define PT_REGS_PARM2(x) ((x)->edx)
+#define PT_REGS_PARM3(x) ((x)->ecx)
+#define PT_REGS_PARM4(x) 0
+#define PT_REGS_PARM5(x) 0
+#define PT_REGS_RET(x) ((x)->esp)
+#define PT_REGS_FP(x) ((x)->ebp)
+#define PT_REGS_RC(x) ((x)->eax)
+#define PT_REGS_SP(x) ((x)->esp)
+#define PT_REGS_IP(x) ((x)->eip)
+#else
+#define PT_REGS_PARM1(x) ((x)->rdi)
+#define PT_REGS_PARM2(x) ((x)->rsi)
+#define PT_REGS_PARM3(x) ((x)->rdx)
+#define PT_REGS_PARM4(x) ((x)->rcx)
+#define PT_REGS_PARM5(x) ((x)->r8)
+#define PT_REGS_RET(x) ((x)->rsp)
+#define PT_REGS_FP(x) ((x)->rbp)
+#define PT_REGS_RC(x) ((x)->rax)
+#define PT_REGS_SP(x) ((x)->rsp)
+#define PT_REGS_IP(x) ((x)->rip)
+#endif
+#endif
+
+#elif defined(bpf_target_s390)
+
+/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
+struct pt_regs;
+#define PT_REGS_S390 const volatile user_pt_regs
+#define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2])
+#define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3])
+#define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4])
+#define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5])
+#define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6])
+#define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14])
+/* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11])
+#define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2])
+#define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15])
+#define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr)
+
+#elif defined(bpf_target_arm)
+
+#define PT_REGS_PARM1(x) ((x)->uregs[0])
+#define PT_REGS_PARM2(x) ((x)->uregs[1])
+#define PT_REGS_PARM3(x) ((x)->uregs[2])
+#define PT_REGS_PARM4(x) ((x)->uregs[3])
+#define PT_REGS_PARM5(x) ((x)->uregs[4])
+#define PT_REGS_RET(x) ((x)->uregs[14])
+#define PT_REGS_FP(x) ((x)->uregs[11]) /* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_RC(x) ((x)->uregs[0])
+#define PT_REGS_SP(x) ((x)->uregs[13])
+#define PT_REGS_IP(x) ((x)->uregs[12])
+
+#elif defined(bpf_target_arm64)
+
+/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
+struct pt_regs;
+#define PT_REGS_ARM64 const volatile struct user_pt_regs
+#define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0])
+#define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1])
+#define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2])
+#define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3])
+#define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4])
+#define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30])
+/* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29])
+#define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0])
+#define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp)
+#define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc)
+
+#elif defined(bpf_target_mips)
+
+#define PT_REGS_PARM1(x) ((x)->regs[4])
+#define PT_REGS_PARM2(x) ((x)->regs[5])
+#define PT_REGS_PARM3(x) ((x)->regs[6])
+#define PT_REGS_PARM4(x) ((x)->regs[7])
+#define PT_REGS_PARM5(x) ((x)->regs[8])
+#define PT_REGS_RET(x) ((x)->regs[31])
+#define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */
+#define PT_REGS_RC(x) ((x)->regs[1])
+#define PT_REGS_SP(x) ((x)->regs[29])
+#define PT_REGS_IP(x) ((x)->cp0_epc)
+
+#elif defined(bpf_target_powerpc)
+
+#define PT_REGS_PARM1(x) ((x)->gpr[3])
+#define PT_REGS_PARM2(x) ((x)->gpr[4])
+#define PT_REGS_PARM3(x) ((x)->gpr[5])
+#define PT_REGS_PARM4(x) ((x)->gpr[6])
+#define PT_REGS_PARM5(x) ((x)->gpr[7])
+#define PT_REGS_RC(x) ((x)->gpr[3])
+#define PT_REGS_SP(x) ((x)->sp)
+#define PT_REGS_IP(x) ((x)->nip)
+
+#elif defined(bpf_target_sparc)
+
+#define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0])
+#define PT_REGS_PARM2(x) ((x)->u_regs[UREG_I1])
+#define PT_REGS_PARM3(x) ((x)->u_regs[UREG_I2])
+#define PT_REGS_PARM4(x) ((x)->u_regs[UREG_I3])
+#define PT_REGS_PARM5(x) ((x)->u_regs[UREG_I4])
+#define PT_REGS_RET(x) ((x)->u_regs[UREG_I7])
+#define PT_REGS_RC(x) ((x)->u_regs[UREG_I0])
+#define PT_REGS_SP(x) ((x)->u_regs[UREG_FP])
+
+/* Should this also be a bpf_target check for the sparc case? */
+#if defined(__arch64__)
+#define PT_REGS_IP(x) ((x)->tpc)
+#else
+#define PT_REGS_IP(x) ((x)->pc)
+#endif
+
+#endif
+
+#if defined(bpf_target_powerpc)
+#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = (ctx)->link; })
+#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
+#elif defined(bpf_target_sparc)
+#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = PT_REGS_RET(ctx); })
+#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
+#else
+#define BPF_KPROBE_READ_RET_IP(ip, ctx)					    \
+	({ bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
+#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)				    \
+	({ bpf_probe_read(&(ip), sizeof(ip),				    \
+			  (void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
+#endif
+
+#endif
diff --git a/tools/testing/selftests/bpf/progs/loop1.c b/tools/testing/selftests/bpf/progs/loop1.c
index 7cdb7f878310..40ac722a9da5 100644
--- a/tools/testing/selftests/bpf/progs/loop1.c
+++ b/tools/testing/selftests/bpf/progs/loop1.c
@@ -7,6 +7,7 @@
 #include <stdbool.h>
 #include <linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 char _license[] SEC("license") = "GPL";
 
diff --git a/tools/testing/selftests/bpf/progs/loop2.c b/tools/testing/selftests/bpf/progs/loop2.c
index 9b2f808a2863..bb80f29aa7f7 100644
--- a/tools/testing/selftests/bpf/progs/loop2.c
+++ b/tools/testing/selftests/bpf/progs/loop2.c
@@ -7,6 +7,7 @@
 #include <stdbool.h>
 #include <linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 char _license[] SEC("license") = "GPL";
 
diff --git a/tools/testing/selftests/bpf/progs/loop3.c b/tools/testing/selftests/bpf/progs/loop3.c
index d727657d51e2..2b9165a7afe1 100644
--- a/tools/testing/selftests/bpf/progs/loop3.c
+++ b/tools/testing/selftests/bpf/progs/loop3.c
@@ -7,6 +7,7 @@
 #include <stdbool.h>
 #include <linux/bpf.h>
 #include "bpf_helpers.h"
+#include "bpf_tracing.h"
 
 char _license[] SEC("license") = "GPL";
 
-- 
2.17.1


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

* [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
                   ` (3 preceding siblings ...)
  2019-10-02 21:50 ` [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-03 20:22   ` Song Liu
  2019-10-02 21:50 ` [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers Andrii Nakryiko
  2019-10-02 21:50 ` [PATCH v2 bpf-next 7/7] selftests/bpf: add BPF_CORE_READ and BPF_CORE_READ_STR_INTO macro tests Andrii Nakryiko
  6 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Move bpf_helpers.h, bpf_tracing.h, and bpf_endian.h into libbpf. Ensure
they are installed along the other libbpf headers. Also, adjust
selftests and samples include path to include libbpf now.

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 samples/bpf/Makefile                               | 2 +-
 tools/lib/bpf/Makefile                             | 5 ++++-
 tools/{testing/selftests => lib}/bpf/bpf_endian.h  | 0
 tools/{testing/selftests => lib}/bpf/bpf_helpers.h | 0
 tools/{testing/selftests => lib}/bpf/bpf_tracing.h | 0
 tools/testing/selftests/bpf/Makefile               | 2 +-
 6 files changed, 6 insertions(+), 3 deletions(-)
 rename tools/{testing/selftests => lib}/bpf/bpf_endian.h (100%)
 rename tools/{testing/selftests => lib}/bpf/bpf_helpers.h (100%)
 rename tools/{testing/selftests => lib}/bpf/bpf_tracing.h (100%)

diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 42b571cde177..ecb3535d91e3 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -283,7 +283,7 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
 $(obj)/%.o: $(src)/%.c
 	@echo "  CLANG-bpf " $@
 	$(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(EXTRA_CFLAGS) -I$(obj) \
-		-I$(srctree)/tools/testing/selftests/bpf/ \
+		-I$(srctree)/tools/testing/selftests/bpf/ -I$(srctree)/tools/lib/bpf/ \
 		-D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \
 		-D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \
 		-Wno-gnu-variable-sized-type-not-at-end \
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index c6f94cffe06e..20b5b0ff5c73 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -240,7 +240,10 @@ install_headers:
 		$(call do_install,libbpf.h,$(prefix)/include/bpf,644); \
 		$(call do_install,btf.h,$(prefix)/include/bpf,644); \
 		$(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \
-		$(call do_install,xsk.h,$(prefix)/include/bpf,644);
+		$(call do_install,xsk.h,$(prefix)/include/bpf,644); \
+		$(call do_install,bpf_helpers.h,$(prefix)/include/bpf,644); \
+		$(call do_install,bpf_tracing.h,$(prefix)/include/bpf,644); \
+		$(call do_install,bpf_endian.h,$(prefix)/include/bpf,644);
 
 install_pkgconfig: $(PC_FILE)
 	$(call QUIET_INSTALL, $(PC_FILE)) \
diff --git a/tools/testing/selftests/bpf/bpf_endian.h b/tools/lib/bpf/bpf_endian.h
similarity index 100%
rename from tools/testing/selftests/bpf/bpf_endian.h
rename to tools/lib/bpf/bpf_endian.h
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
similarity index 100%
rename from tools/testing/selftests/bpf/bpf_helpers.h
rename to tools/lib/bpf/bpf_helpers.h
diff --git a/tools/testing/selftests/bpf/bpf_tracing.h b/tools/lib/bpf/bpf_tracing.h
similarity index 100%
rename from tools/testing/selftests/bpf/bpf_tracing.h
rename to tools/lib/bpf/bpf_tracing.h
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 6889c19a628c..b00a5d8046c7 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -148,7 +148,7 @@ $(shell $(1) -v -E - </dev/null 2>&1 \
 endef
 CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG))
 BPF_CFLAGS = -I. -I./include/uapi -I../../../include/uapi \
-	     -I$(OUTPUT)/../usr/include -D__TARGET_ARCH_$(SRCARCH)
+	     -I$(BPFDIR) -I$(OUTPUT)/../usr/include -D__TARGET_ARCH_$(SRCARCH)
 
 CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \
 	       -Wno-compare-distinct-pointer-types
-- 
2.17.1


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

* [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
                   ` (4 preceding siblings ...)
  2019-10-02 21:50 ` [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  2019-10-03 20:35   ` Song Liu
  2019-10-02 21:50 ` [PATCH v2 bpf-next 7/7] selftests/bpf: add BPF_CORE_READ and BPF_CORE_READ_STR_INTO macro tests Andrii Nakryiko
  6 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Add few macros simplifying BCC-like multi-level probe reads, while also
emitting CO-RE relocations for each read.

Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 tools/lib/bpf/bpf_helpers.h | 143 ++++++++++++++++++++++++++++++++++++
 1 file changed, 143 insertions(+)

diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
index cb9d4d2224af..847dfd7125e4 100644
--- a/tools/lib/bpf/bpf_helpers.h
+++ b/tools/lib/bpf/bpf_helpers.h
@@ -19,6 +19,10 @@
  */
 #define SEC(NAME) __attribute__((section(NAME), used))
 
+#ifndef __always_inline
+#define __always_inline __attribute__((always_inline))
+#endif
+
 /* helper functions called from eBPF programs written in C */
 static void *(*bpf_map_lookup_elem)(void *map, const void *key) =
 	(void *) BPF_FUNC_map_lookup_elem;
@@ -312,4 +316,143 @@ struct bpf_map_def {
 	bpf_probe_read(dst, sz,						    \
 		       (const void *)__builtin_preserve_access_index(src))
 
+/*
+ * bpf_core_read_str() is a thin wrapper around bpf_probe_read_str()
+ * additionally emitting BPF CO-RE field relocation for specified source
+ * argument.
+ */
+#define bpf_core_read_str(dst, sz, src)					    \
+	bpf_probe_read_str(dst, sz,					    \
+			   (const void *)__builtin_preserve_access_index(src))
+
+#define ___concat(a, b) a ## b
+#define ___apply(fn, n) ___concat(fn, n)
+#define ___nth(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, __11, N, ...) N
+
+/* return number of provided arguments; used for switch-based variadic macro
+ * definitions (see ___last, ___arrow, etc below)
+ */
+#define ___narg(...) ___nth(_, ##__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+/* return 0 if no arguments are passed, N - otherwise; used for
+ * recursively-defined macros to specify termination (0) case, and generic
+ * (N) case (e.g., ___read_ptrs, ___core_read)
+ */
+#define ___empty(...) ___nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0)
+
+#define ___last1(x) x
+#define ___last2(a, x) x
+#define ___last3(a, b, x) x
+#define ___last4(a, b, c, x) x
+#define ___last5(a, b, c, d, x) x
+#define ___last6(a, b, c, d, e, x) x
+#define ___last7(a, b, c, d, e, f, x) x
+#define ___last8(a, b, c, d, e, f, g, x) x
+#define ___last9(a, b, c, d, e, f, g, h, x) x
+#define ___last10(a, b, c, d, e, f, g, h, i, x) x
+#define ___last(...) ___apply(___last, ___narg(__VA_ARGS__))(__VA_ARGS__)
+
+#define ___nolast2(a, _) a
+#define ___nolast3(a, b, _) a, b
+#define ___nolast4(a, b, c, _) a, b, c
+#define ___nolast5(a, b, c, d, _) a, b, c, d
+#define ___nolast6(a, b, c, d, e, _) a, b, c, d, e
+#define ___nolast7(a, b, c, d, e, f, _) a, b, c, d, e, f
+#define ___nolast8(a, b, c, d, e, f, g, _) a, b, c, d, e, f, g
+#define ___nolast9(a, b, c, d, e, f, g, h, _) a, b, c, d, e, f, g, h
+#define ___nolast10(a, b, c, d, e, f, g, h, i, _) a, b, c, d, e, f, g, h, i
+#define ___nolast(...) ___apply(___nolast, ___narg(__VA_ARGS__))(__VA_ARGS__)
+
+#define ___arrow1(a) a
+#define ___arrow2(a, b) a->b
+#define ___arrow3(a, b, c) a->b->c
+#define ___arrow4(a, b, c, d) a->b->c->d
+#define ___arrow5(a, b, c, d, e) a->b->c->d->e
+#define ___arrow6(a, b, c, d, e, f) a->b->c->d->e->f
+#define ___arrow7(a, b, c, d, e, f, g) a->b->c->d->e->f->g
+#define ___arrow8(a, b, c, d, e, f, g, h) a->b->c->d->e->f->g->h
+#define ___arrow9(a, b, c, d, e, f, g, h, i) a->b->c->d->e->f->g->h->i
+#define ___arrow10(a, b, c, d, e, f, g, h, i, j) a->b->c->d->e->f->g->h->i->j
+#define ___arrow(...) ___apply(___arrow, ___narg(__VA_ARGS__))(__VA_ARGS__)
+
+#define ___type(...) typeof(___arrow(__VA_ARGS__))
+
+#define ___read(read_fn, dst, src_type, src, accessor)			    \
+	read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
+
+/* "recursively" read a sequence of inner pointers using local __t var */
+#define ___rd_last(...)							    \
+	___read(bpf_core_read, &__t,					    \
+		___type(___nolast(__VA_ARGS__)), __t, ___last(__VA_ARGS__));
+#define ___rd_p0(src) const void *__t = src;
+#define ___rd_p1(...) ___rd_p0(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p2(...) ___rd_p1(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p3(...) ___rd_p2(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p4(...) ___rd_p3(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p5(...) ___rd_p4(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p6(...) ___rd_p5(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p7(...) ___rd_p6(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p8(...) ___rd_p7(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___rd_p9(...) ___rd_p8(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
+#define ___read_ptrs(src, ...)						    \
+	___apply(___rd_p, ___narg(__VA_ARGS__))(src, __VA_ARGS__)
+
+#define ___core_read0(fn, dst, src, a)					    \
+	___read(fn, dst, ___type(src), src, a);
+#define ___core_readN(fn, dst, src, ...)				    \
+	___read_ptrs(src, ___nolast(__VA_ARGS__))			    \
+	___read(fn, dst, ___type(src, ___nolast(__VA_ARGS__)), __t,	    \
+		___last(__VA_ARGS__));
+#define ___core_read(fn, dst, src, a, ...)				    \
+	___apply(___core_read, ___empty(__VA_ARGS__))(fn, dst,		    \
+						      src, a, ##__VA_ARGS__)
+
+/*
+ * BPF_CORE_READ_INTO() is a more performance-conscious variant of
+ * BPF_CORE_READ(), in which final field is read into user-provided storage.
+ * See BPF_CORE_READ() below for more details on general usage.
+ */
+#define BPF_CORE_READ_INTO(dst, src, a, ...)				    \
+	({								    \
+		___core_read(bpf_core_read, dst, src, a, ##__VA_ARGS__)	    \
+	})
+
+/*
+ * BPF_CORE_READ_STR_INTO() does same "pointer chasing" as
+ * BPF_CORE_READ() for intermediate pointers, but then executes (and returns
+ * corresponding error code) bpf_core_read_str() for final string read.
+ */
+#define BPF_CORE_READ_STR_INTO(dst, src, a, ...)			    \
+	({								    \
+		___core_read(bpf_core_read_str, dst, src, a, ##__VA_ARGS__) \
+	})
+
+/*
+ * BPF_CORE_READ() is used to simplify BPF CO-RE relocatable read, especially
+ * when there are few pointer chasing steps.
+ * E.g., what in non-BPF world (or in BPF w/ BCC) would be something like:
+ *	int x = s->a.b.c->d.e->f->g;
+ * can be succinctly achieved using BPF_CORE_READ as:
+ *	int x = BPF_CORE_READ(s, a.b.c, d.e, f, g);
+ *
+ * BPF_CORE_READ will decompose above statement into 4 bpf_core_read (BPF
+ * CO-RE relocatable bpf_probe_read() wrapper) calls, logically equivalent to:
+ * 1. const void *__t = s->a.b.c;
+ * 2. __t = __t->d.e;
+ * 3. __t = __t->f;
+ * 4. return __t->g;
+ *
+ * Equivalence is logical, because there is a heavy type casting/preservation
+ * involved, as well as all the reads are happening through bpf_probe_read()
+ * calls using __builtin_preserve_access_index() to emit CO-RE relocations.
+ *
+ * N.B. Only up to 9 "field accessors" are supported, which should be more
+ * than enough for any practical purpose.
+ */
+#define BPF_CORE_READ(src, a, ...)					    \
+	({								    \
+		___type(src, a, ##__VA_ARGS__) __r;			    \
+		BPF_CORE_READ_INTO(&__r, src, a, ##__VA_ARGS__);	    \
+		__r;							    \
+	})
+
 #endif
-- 
2.17.1


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

* [PATCH v2 bpf-next 7/7] selftests/bpf: add BPF_CORE_READ and BPF_CORE_READ_STR_INTO macro tests
  2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
                   ` (5 preceding siblings ...)
  2019-10-02 21:50 ` [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers Andrii Nakryiko
@ 2019-10-02 21:50 ` Andrii Nakryiko
  6 siblings, 0 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-02 21:50 UTC (permalink / raw)
  To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Validate BPF_CORE_READ correctness and handling of up to 9 levels of
nestedness using cyclic task->(group_leader->)*->tgid chains.

Also add a test of maximum-dpeth BPF_CORE_READ_STR_INTO() macro.

Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
 .../selftests/bpf/prog_tests/core_reloc.c     |  8 ++-
 .../selftests/bpf/progs/core_reloc_types.h    |  9 ++++
 .../bpf/progs/test_core_reloc_kernel.c        | 54 ++++++++++++++++++-
 3 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
index f3863f976a48..21a0dff66241 100644
--- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c
+++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
@@ -193,8 +193,12 @@ static struct core_reloc_test_case test_cases[] = {
 		.btf_src_file = NULL, /* load from /lib/modules/$(uname -r) */
 		.input = "",
 		.input_len = 0,
-		.output = "\1", /* true */
-		.output_len = 1,
+		.output = STRUCT_TO_CHAR_PTR(core_reloc_kernel_output) {
+			.valid = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, },
+			.comm = "test_progs\0\0\0\0\0",
+			.comm_len = 11,
+		},
+		.output_len = sizeof(struct core_reloc_kernel_output),
 	},
 
 	/* validate BPF program can use multiple flavors to match against
diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h
index f686a8138d90..9a6bdeb4894c 100644
--- a/tools/testing/selftests/bpf/progs/core_reloc_types.h
+++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h
@@ -1,5 +1,14 @@
 #include <stdint.h>
 #include <stdbool.h>
+/*
+ * KERNEL
+ */
+
+struct core_reloc_kernel_output {
+	int valid[10];
+	char comm[16];
+	int comm_len;
+};
 
 /*
  * FLAVORS
diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
index e5308026cfda..f318d39623b5 100644
--- a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
+++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
@@ -12,9 +12,17 @@ static volatile struct data {
 	char out[256];
 } data;
 
+struct core_reloc_kernel_output {
+	int valid[10];
+	char comm[16];
+	int comm_len;
+};
+
 struct task_struct {
 	int pid;
 	int tgid;
+	char comm[16];
+	struct task_struct *group_leader;
 };
 
 #define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
@@ -23,7 +31,9 @@ SEC("raw_tracepoint/sys_enter")
 int test_core_kernel(void *ctx)
 {
 	struct task_struct *task = (void *)bpf_get_current_task();
+	struct core_reloc_kernel_output *out = (void *)&data.out;
 	uint64_t pid_tgid = bpf_get_current_pid_tgid();
+	uint32_t real_tgid = (uint32_t)pid_tgid;
 	int pid, tgid;
 
 	if (CORE_READ(&pid, &task->pid) ||
@@ -31,7 +41,49 @@ int test_core_kernel(void *ctx)
 		return 1;
 
 	/* validate pid + tgid matches */
-	data.out[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid;
+	out->valid[0] = (((uint64_t)pid << 32) | tgid) == pid_tgid;
+
+	/* test variadic BPF_CORE_READ macros */
+	out->valid[1] = BPF_CORE_READ(task,
+				      tgid) == real_tgid;
+	out->valid[2] = BPF_CORE_READ(task,
+				      group_leader,
+				      tgid) == real_tgid;
+	out->valid[3] = BPF_CORE_READ(task,
+				      group_leader, group_leader,
+				      tgid) == real_tgid;
+	out->valid[4] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      tgid) == real_tgid;
+	out->valid[5] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      group_leader,
+				      tgid) == real_tgid;
+	out->valid[6] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      group_leader, group_leader,
+				      tgid) == real_tgid;
+	out->valid[7] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      group_leader, group_leader, group_leader,
+				      tgid) == real_tgid;
+	out->valid[8] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      group_leader, group_leader, group_leader,
+				      group_leader,
+				      tgid) == real_tgid;
+	out->valid[9] = BPF_CORE_READ(task,
+				      group_leader, group_leader, group_leader,
+				      group_leader, group_leader, group_leader,
+				      group_leader, group_leader,
+				      tgid) == real_tgid;
+
+	/* test BPF_CORE_READ_STR_INTO() returns correct code and contents */
+	out->comm_len = BPF_CORE_READ_STR_INTO(
+		&out->comm, task,
+		group_leader, group_leader, group_leader, group_leader,
+		group_leader, group_leader, group_leader, group_leader,
+		comm);
 
 	return 0;
 }
-- 
2.17.1


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

* Re: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
@ 2019-10-03  7:35   ` Toke Høiland-Jørgensen
  2019-10-03 16:20     ` Andrii Nakryiko
  2019-10-03 17:31   ` John Fastabend
  2019-10-03 20:08   ` Song Liu
  2 siblings, 1 reply; 26+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-10-03  7:35 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, netdev, ast, daniel
  Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Andrii Nakryiko <andriin@fb.com> writes:

> diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c
> index 2b2ffb97018b..f47ee513cb7c 100644
> --- a/samples/bpf/map_perf_test_kern.c
> +++ b/samples/bpf/map_perf_test_kern.c
> @@ -9,25 +9,26 @@
>  #include <linux/version.h>
>  #include <uapi/linux/bpf.h>
>  #include "bpf_helpers.h"
> +#include "bpf_legacy.h"
>  
>  #define MAX_ENTRIES 1000
>  #define MAX_NR_CPUS 1024
>  
> -struct bpf_map_def SEC("maps") hash_map = {
> +struct bpf_map_def_legacy SEC("maps") hash_map = {
>  	.type = BPF_MAP_TYPE_HASH,
>  	.key_size = sizeof(u32),
>  	.value_size = sizeof(long),
>  	.max_entries = MAX_ENTRIES,
>  };

Why switch these when they're not actually using any of the extra fields
in map_def_legacy?
>  
> -struct bpf_map_def SEC("maps") lru_hash_map = {
> +struct bpf_map_def_legacy SEC("maps") lru_hash_map = {
>  	.type = BPF_MAP_TYPE_LRU_HASH,
>  	.key_size = sizeof(u32),
>  	.value_size = sizeof(long),
>  	.max_entries = 10000,
>  };
>  
> -struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
> +struct bpf_map_def_legacy SEC("maps") nocommon_lru_hash_map = {
>  	.type = BPF_MAP_TYPE_LRU_HASH,
>  	.key_size = sizeof(u32),
>  	.value_size = sizeof(long),
> @@ -35,7 +36,7 @@ struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
>  	.map_flags = BPF_F_NO_COMMON_LRU,
>  };
>  
> -struct bpf_map_def SEC("maps") inner_lru_hash_map = {
> +struct bpf_map_def_legacy SEC("maps") inner_lru_hash_map = {
>  	.type = BPF_MAP_TYPE_LRU_HASH,
>  	.key_size = sizeof(u32),
>  	.value_size = sizeof(long),
> @@ -44,20 +45,20 @@ struct bpf_map_def SEC("maps") inner_lru_hash_map = {
>  	.numa_node = 0,
>  };

Or are you just switching everything because of this one?


-Toke


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

* Re: [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-02 21:50 ` [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h Andrii Nakryiko
@ 2019-10-03  7:35   ` Toke Høiland-Jørgensen
  2019-10-03 16:22     ` Andrii Nakryiko
  2019-10-03 17:33   ` John Fastabend
  1 sibling, 1 reply; 26+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-10-03  7:35 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, netdev, ast, daniel
  Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Andrii Nakryiko <andriin@fb.com> writes:

> +/* a helper structure used by eBPF C program
> + * to describe BPF map attributes to libbpf loader
> + */
> +struct bpf_map_def {
> +	unsigned int type;
> +	unsigned int key_size;
> +	unsigned int value_size;
> +	unsigned int max_entries;
> +	unsigned int map_flags;
> +};

Why is this still here? There's already an identical definition in libbpf.h...

-Toke


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

* Re: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
@ 2019-10-03 16:20     ` Andrii Nakryiko
  2019-10-03 16:27       ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 16:20 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 12:35 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> Andrii Nakryiko <andriin@fb.com> writes:
>
> > diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c
> > index 2b2ffb97018b..f47ee513cb7c 100644
> > --- a/samples/bpf/map_perf_test_kern.c
> > +++ b/samples/bpf/map_perf_test_kern.c
> > @@ -9,25 +9,26 @@
> >  #include <linux/version.h>
> >  #include <uapi/linux/bpf.h>
> >  #include "bpf_helpers.h"
> > +#include "bpf_legacy.h"
> >
> >  #define MAX_ENTRIES 1000
> >  #define MAX_NR_CPUS 1024
> >
> > -struct bpf_map_def SEC("maps") hash_map = {
> > +struct bpf_map_def_legacy SEC("maps") hash_map = {
> >       .type = BPF_MAP_TYPE_HASH,
> >       .key_size = sizeof(u32),
> >       .value_size = sizeof(long),
> >       .max_entries = MAX_ENTRIES,
> >  };
>
> Why switch these when they're not actually using any of the extra fields
> in map_def_legacy?

See below, they have to be uniform-sized.

> >
> > -struct bpf_map_def SEC("maps") lru_hash_map = {
> > +struct bpf_map_def_legacy SEC("maps") lru_hash_map = {
> >       .type = BPF_MAP_TYPE_LRU_HASH,
> >       .key_size = sizeof(u32),
> >       .value_size = sizeof(long),
> >       .max_entries = 10000,
> >  };
> >
> > -struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
> > +struct bpf_map_def_legacy SEC("maps") nocommon_lru_hash_map = {
> >       .type = BPF_MAP_TYPE_LRU_HASH,
> >       .key_size = sizeof(u32),
> >       .value_size = sizeof(long),
> > @@ -35,7 +36,7 @@ struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
> >       .map_flags = BPF_F_NO_COMMON_LRU,
> >  };
> >
> > -struct bpf_map_def SEC("maps") inner_lru_hash_map = {
> > +struct bpf_map_def_legacy SEC("maps") inner_lru_hash_map = {
> >       .type = BPF_MAP_TYPE_LRU_HASH,
> >       .key_size = sizeof(u32),
> >       .value_size = sizeof(long),
> > @@ -44,20 +45,20 @@ struct bpf_map_def SEC("maps") inner_lru_hash_map = {
> >       .numa_node = 0,
> >  };
>
> Or are you just switching everything because of this one?

Exactly. Another way would be to switch all but this to BTF-based one,
but I didn't want to make this patch set even bigger, we can always do
that later
.
>
>
> -Toke
>

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

* Re: [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
@ 2019-10-03 16:22     ` Andrii Nakryiko
  2019-10-03 17:21       ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 16:22 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 12:35 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> Andrii Nakryiko <andriin@fb.com> writes:
>
> > +/* a helper structure used by eBPF C program
> > + * to describe BPF map attributes to libbpf loader
> > + */
> > +struct bpf_map_def {
> > +     unsigned int type;
> > +     unsigned int key_size;
> > +     unsigned int value_size;
> > +     unsigned int max_entries;
> > +     unsigned int map_flags;
> > +};
>
> Why is this still here? There's already an identical definition in libbpf.h...
>

It's a BPF (kernel) side vs userspace side difference. bpf_helpers.h
are included from BPF program, while libbpf.h won't work on kernel
side. So we have to have a duplicate of bpf_map_def.

> -Toke
>

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

* Re: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-03 16:20     ` Andrii Nakryiko
@ 2019-10-03 16:27       ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 26+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-10-03 16:27 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:

> On Thu, Oct 3, 2019 at 12:35 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> Andrii Nakryiko <andriin@fb.com> writes:
>>
>> > diff --git a/samples/bpf/map_perf_test_kern.c b/samples/bpf/map_perf_test_kern.c
>> > index 2b2ffb97018b..f47ee513cb7c 100644
>> > --- a/samples/bpf/map_perf_test_kern.c
>> > +++ b/samples/bpf/map_perf_test_kern.c
>> > @@ -9,25 +9,26 @@
>> >  #include <linux/version.h>
>> >  #include <uapi/linux/bpf.h>
>> >  #include "bpf_helpers.h"
>> > +#include "bpf_legacy.h"
>> >
>> >  #define MAX_ENTRIES 1000
>> >  #define MAX_NR_CPUS 1024
>> >
>> > -struct bpf_map_def SEC("maps") hash_map = {
>> > +struct bpf_map_def_legacy SEC("maps") hash_map = {
>> >       .type = BPF_MAP_TYPE_HASH,
>> >       .key_size = sizeof(u32),
>> >       .value_size = sizeof(long),
>> >       .max_entries = MAX_ENTRIES,
>> >  };
>>
>> Why switch these when they're not actually using any of the extra fields
>> in map_def_legacy?
>
> See below, they have to be uniform-sized.
>
>> >
>> > -struct bpf_map_def SEC("maps") lru_hash_map = {
>> > +struct bpf_map_def_legacy SEC("maps") lru_hash_map = {
>> >       .type = BPF_MAP_TYPE_LRU_HASH,
>> >       .key_size = sizeof(u32),
>> >       .value_size = sizeof(long),
>> >       .max_entries = 10000,
>> >  };
>> >
>> > -struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
>> > +struct bpf_map_def_legacy SEC("maps") nocommon_lru_hash_map = {
>> >       .type = BPF_MAP_TYPE_LRU_HASH,
>> >       .key_size = sizeof(u32),
>> >       .value_size = sizeof(long),
>> > @@ -35,7 +36,7 @@ struct bpf_map_def SEC("maps") nocommon_lru_hash_map = {
>> >       .map_flags = BPF_F_NO_COMMON_LRU,
>> >  };
>> >
>> > -struct bpf_map_def SEC("maps") inner_lru_hash_map = {
>> > +struct bpf_map_def_legacy SEC("maps") inner_lru_hash_map = {
>> >       .type = BPF_MAP_TYPE_LRU_HASH,
>> >       .key_size = sizeof(u32),
>> >       .value_size = sizeof(long),
>> > @@ -44,20 +45,20 @@ struct bpf_map_def SEC("maps") inner_lru_hash_map = {
>> >       .numa_node = 0,
>> >  };
>>
>> Or are you just switching everything because of this one?
>
> Exactly. Another way would be to switch all but this to BTF-based one,
> but I didn't want to make this patch set even bigger, we can always do
> that later

Right, fair enough :)

-Toke


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

* Re: [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-03 16:22     ` Andrii Nakryiko
@ 2019-10-03 17:21       ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 26+ messages in thread
From: Toke Høiland-Jørgensen @ 2019-10-03 17:21 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:

> On Thu, Oct 3, 2019 at 12:35 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>>
>> Andrii Nakryiko <andriin@fb.com> writes:
>>
>> > +/* a helper structure used by eBPF C program
>> > + * to describe BPF map attributes to libbpf loader
>> > + */
>> > +struct bpf_map_def {
>> > +     unsigned int type;
>> > +     unsigned int key_size;
>> > +     unsigned int value_size;
>> > +     unsigned int max_entries;
>> > +     unsigned int map_flags;
>> > +};
>>
>> Why is this still here? There's already an identical definition in libbpf.h...
>>
>
> It's a BPF (kernel) side vs userspace side difference. bpf_helpers.h
> are included from BPF program, while libbpf.h won't work on kernel
> side. So we have to have a duplicate of bpf_map_def.

Ah, yes, of course. Silly me :)

-Toke


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

* RE: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
@ 2019-10-03 17:31   ` John Fastabend
  2019-10-03 20:08   ` Song Liu
  2 siblings, 0 replies; 26+ messages in thread
From: John Fastabend @ 2019-10-03 17:31 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, netdev, ast, daniel
  Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Andrii Nakryiko wrote:
> Split off few legacy things from bpf_helpers.h into separate
> bpf_legacy.h file:
> - load_{byte|half|word};
> - remove extra inner_idx and numa_node fields from bpf_map_def and
>   introduce bpf_map_def_legacy for use in samples;
> - move BPF_ANNOTATE_KV_PAIR into bpf_legacy.h.
> 
> Adjust samples and selftests accordingly by either including
> bpf_legacy.h and using bpf_map_def_legacy, or switching to BTF-defined
> maps altogether.
> 
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---

Eventually we convert tests to use bpf_create_map_in_map() and friends
so we can drop legacy. Assuming this is what you have in mind but agree
thats a next step.

Acked-by: John Fastabend <john.fastabend@gmail.com>

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

* RE: [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-02 21:50 ` [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h Andrii Nakryiko
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
@ 2019-10-03 17:33   ` John Fastabend
  2019-10-03 20:18     ` Song Liu
  1 sibling, 1 reply; 26+ messages in thread
From: John Fastabend @ 2019-10-03 17:33 UTC (permalink / raw)
  To: Andrii Nakryiko, bpf, netdev, ast, daniel
  Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko

Andrii Nakryiko wrote:
> Split-off PT_REGS-related helpers into bpf_tracing.h header. Adjust
> selftests and samples to include it where necessary.
> 
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---

Acked-by: John Fastabend <john.fastabend@gmail.com>

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

* Re: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
  2019-10-03  7:35   ` Toke Høiland-Jørgensen
  2019-10-03 17:31   ` John Fastabend
@ 2019-10-03 20:08   ` Song Liu
  2019-10-03 21:22     ` Andrii Nakryiko
  2 siblings, 1 reply; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:08 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: bpf, Networking, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Kernel Team

On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
>
> Split off few legacy things from bpf_helpers.h into separate
> bpf_legacy.h file:
> - load_{byte|half|word};
> - remove extra inner_idx and numa_node fields from bpf_map_def and
>   introduce bpf_map_def_legacy for use in samples;
> - move BPF_ANNOTATE_KV_PAIR into bpf_legacy.h.
>
> Adjust samples and selftests accordingly by either including
> bpf_legacy.h and using bpf_map_def_legacy, or switching to BTF-defined
> maps altogether.
>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>

Acked-by: Song Liu <songliubraving@fb.com>

with a nit below

> ---
>  samples/bpf/hbm_kern.h                        | 28 +++++++------
>  samples/bpf/map_perf_test_kern.c              | 23 +++++------
>  samples/bpf/parse_ldabs.c                     |  1 +
>  samples/bpf/sockex1_kern.c                    |  1 +
>  samples/bpf/sockex2_kern.c                    |  1 +
>  samples/bpf/sockex3_kern.c                    |  1 +
>  samples/bpf/tcbpf1_kern.c                     |  1 +
>  samples/bpf/test_map_in_map_kern.c            | 15 +++----
>  tools/testing/selftests/bpf/bpf_helpers.h     | 24 +-----------
>  tools/testing/selftests/bpf/bpf_legacy.h      | 39 +++++++++++++++++++
>  .../testing/selftests/bpf/progs/sockopt_sk.c  | 13 +++----
>  tools/testing/selftests/bpf/progs/tcp_rtt.c   | 13 +++----
>  .../selftests/bpf/progs/test_btf_haskv.c      |  1 +
>  .../selftests/bpf/progs/test_btf_newkv.c      |  1 +
>  14 files changed, 92 insertions(+), 70 deletions(-)
>  create mode 100644 tools/testing/selftests/bpf/bpf_legacy.h
>
> diff --git a/samples/bpf/hbm_kern.h b/samples/bpf/hbm_kern.h
> index aa207a2eebbd..91880a0e9c2f 100644
> --- a/samples/bpf/hbm_kern.h
> +++ b/samples/bpf/hbm_kern.h
> @@ -24,6 +24,7 @@
>  #include <net/inet_ecn.h>
>  #include "bpf_endian.h"
>  #include "bpf_helpers.h"
> +#include "bpf_legacy.h"

nit: I guess we don't need bpf_legacy.h here?

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

* Re: [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  2019-10-02 21:50 ` [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro Andrii Nakryiko
@ 2019-10-03 20:16   ` Song Liu
  2019-10-03 20:28     ` Andrii Nakryiko
  0 siblings, 1 reply; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:16 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: bpf, Networking, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Kernel Team

On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
>
> To allow adding a variadic BPF_CORE_READ macro with slightly different
> syntax and semantics, define CORE_READ in CO-RE reloc tests, which is
> a thin wrapper around low-level bpf_core_read() macro, which in turn is
> just a wrapper around bpf_probe_read().
>
> Acked-by: John Fastabend <john.fastabend@gmail.com>
> Acked-by: Song Liu <songliubraving@fb.com>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---
>  tools/testing/selftests/bpf/bpf_helpers.h      |  8 ++++----
>  .../bpf/progs/test_core_reloc_arrays.c         | 10 ++++++----
>  .../bpf/progs/test_core_reloc_flavors.c        |  8 +++++---
>  .../selftests/bpf/progs/test_core_reloc_ints.c | 18 ++++++++++--------
>  .../bpf/progs/test_core_reloc_kernel.c         |  6 ++++--
>  .../selftests/bpf/progs/test_core_reloc_misc.c |  8 +++++---
>  .../selftests/bpf/progs/test_core_reloc_mods.c | 18 ++++++++++--------
>  .../bpf/progs/test_core_reloc_nesting.c        |  6 ++++--
>  .../bpf/progs/test_core_reloc_primitives.c     | 12 +++++++-----
>  .../bpf/progs/test_core_reloc_ptr_as_arr.c     |  4 +++-
>  10 files changed, 58 insertions(+), 40 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
> index 7b75c38238e4..5210cc7d7c5c 100644
> --- a/tools/testing/selftests/bpf/bpf_helpers.h
> +++ b/tools/testing/selftests/bpf/bpf_helpers.h
> @@ -483,7 +483,7 @@ struct pt_regs;
>  #endif
>
>  /*
> - * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset
> + * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
>   * relocation for source address using __builtin_preserve_access_index()
>   * built-in, provided by Clang.
>   *
> @@ -498,8 +498,8 @@ struct pt_regs;
>   * actual field offset, based on target kernel BTF type that matches original
>   * (local) BTF, used to record relocation.
>   */
> -#define BPF_CORE_READ(dst, src)                                                \
> -       bpf_probe_read((dst), sizeof(*(src)),                           \
> -                      __builtin_preserve_access_index(src))
> +#define bpf_core_read(dst, sz, src)                                        \
> +       bpf_probe_read(dst, sz,                                             \
> +                      (const void *)__builtin_preserve_access_index(src))
>
>  #endif
> diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> index bf67f0fdf743..58efe4944594 100644
> --- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> @@ -31,6 +31,8 @@ struct core_reloc_arrays {
>         struct core_reloc_arrays_substruct d[1][2];
>  };
>
> +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)

We are using sizeof(*dst) now, but I guess sizeof(*src) is better?
And it should be sizeof(*(src)).

> +
>  SEC("raw_tracepoint/sys_enter")
>  int test_core_arrays(void *ctx)
>  {
> @@ -38,16 +40,16 @@ int test_core_arrays(void *ctx)
>         struct core_reloc_arrays_output *out = (void *)&data.out;
>
>         /* in->a[2] */
> -       if (BPF_CORE_READ(&out->a2, &in->a[2]))
> +       if (CORE_READ(&out->a2, &in->a[2]))
>                 return 1;
>         /* in->b[1][2][3] */
> -       if (BPF_CORE_READ(&out->b123, &in->b[1][2][3]))
> +       if (CORE_READ(&out->b123, &in->b[1][2][3]))
>                 return 1;
>         /* in->c[1].c */
> -       if (BPF_CORE_READ(&out->c1c, &in->c[1].c))
> +       if (CORE_READ(&out->c1c, &in->c[1].c))
>                 return 1;
>         /* in->d[0][0].d */
> -       if (BPF_CORE_READ(&out->d00d, &in->d[0][0].d))
> +       if (CORE_READ(&out->d00d, &in->d[0][0].d))
>                 return 1;
>
>         return 0;
> diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> index 9fda73e87972..3348acc7e50b 100644
> --- a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> @@ -39,6 +39,8 @@ struct core_reloc_flavors___weird {
>         };
>  };
>
> +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
> +
>  SEC("raw_tracepoint/sys_enter")
>  int test_core_flavors(void *ctx)
>  {
> @@ -48,13 +50,13 @@ int test_core_flavors(void *ctx)
>         struct core_reloc_flavors *out = (void *)&data.out;
>
>         /* read a using weird layout */
> -       if (BPF_CORE_READ(&out->a, &in_weird->a))
> +       if (CORE_READ(&out->a, &in_weird->a))
>                 return 1;
>         /* read b using reversed layout */
> -       if (BPF_CORE_READ(&out->b, &in_rev->b))
> +       if (CORE_READ(&out->b, &in_rev->b))
>                 return 1;
>         /* read c using original layout */
> -       if (BPF_CORE_READ(&out->c, &in_orig->c))
> +       if (CORE_READ(&out->c, &in_orig->c))
>                 return 1;
>
>         return 0;
> diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> index d99233c8008a..cfe16ede48dd 100644
> --- a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> @@ -23,20 +23,22 @@ struct core_reloc_ints {
>         int64_t         s64_field;
>  };
>
> +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)

ditto.

> +
>  SEC("raw_tracepoint/sys_enter")
>  int test_core_ints(void *ctx)
>  {
>         struct core_reloc_ints *in = (void *)&data.in;
>         struct core_reloc_ints *out = (void *)&data.out;
>
> -       if (BPF_CORE_READ(&out->u8_field, &in->u8_field) ||
> -           BPF_CORE_READ(&out->s8_field, &in->s8_field) ||
> -           BPF_CORE_READ(&out->u16_field, &in->u16_field) ||
> -           BPF_CORE_READ(&out->s16_field, &in->s16_field) ||
> -           BPF_CORE_READ(&out->u32_field, &in->u32_field) ||
> -           BPF_CORE_READ(&out->s32_field, &in->s32_field) ||
> -           BPF_CORE_READ(&out->u64_field, &in->u64_field) ||
> -           BPF_CORE_READ(&out->s64_field, &in->s64_field))
> +       if (CORE_READ(&out->u8_field, &in->u8_field) ||
> +           CORE_READ(&out->s8_field, &in->s8_field) ||
> +           CORE_READ(&out->u16_field, &in->u16_field) ||
> +           CORE_READ(&out->s16_field, &in->s16_field) ||
> +           CORE_READ(&out->u32_field, &in->u32_field) ||
> +           CORE_READ(&out->s32_field, &in->s32_field) ||
> +           CORE_READ(&out->u64_field, &in->u64_field) ||
> +           CORE_READ(&out->s64_field, &in->s64_field))
>                 return 1;
>
>         return 0;
> diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> index 37e02aa3f0c8..e5308026cfda 100644
> --- a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> @@ -17,6 +17,8 @@ struct task_struct {
>         int tgid;
>  };
>
> +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
ditto again, and more below.

Thanks,
Song

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

* Re: [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h
  2019-10-03 17:33   ` John Fastabend
@ 2019-10-03 20:18     ` Song Liu
  0 siblings, 0 replies; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:18 UTC (permalink / raw)
  To: John Fastabend
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Andrii Nakryiko, Kernel Team

On Thu, Oct 3, 2019 at 11:10 AM John Fastabend <john.fastabend@gmail.com> wrote:
>
> Andrii Nakryiko wrote:
> > Split-off PT_REGS-related helpers into bpf_tracing.h header. Adjust
> > selftests and samples to include it where necessary.
> >
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > ---
>
> Acked-by: John Fastabend <john.fastabend@gmail.com>

Acked-by: Song Liu <songliubraving@fb.com>

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

* Re: [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf
  2019-10-02 21:50 ` [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf Andrii Nakryiko
@ 2019-10-03 20:22   ` Song Liu
  0 siblings, 0 replies; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:22 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: bpf, Networking, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Kernel Team

On Wed, Oct 2, 2019 at 3:03 PM Andrii Nakryiko <andriin@fb.com> wrote:
>
> Move bpf_helpers.h, bpf_tracing.h, and bpf_endian.h into libbpf. Ensure
> they are installed along the other libbpf headers. Also, adjust
> selftests and samples include path to include libbpf now.
>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>

> ---
>  samples/bpf/Makefile                               | 2 +-
>  tools/lib/bpf/Makefile                             | 5 ++++-
>  tools/{testing/selftests => lib}/bpf/bpf_endian.h  | 0
>  tools/{testing/selftests => lib}/bpf/bpf_helpers.h | 0
>  tools/{testing/selftests => lib}/bpf/bpf_tracing.h | 0
>  tools/testing/selftests/bpf/Makefile               | 2 +-
>  6 files changed, 6 insertions(+), 3 deletions(-)
>  rename tools/{testing/selftests => lib}/bpf/bpf_endian.h (100%)
>  rename tools/{testing/selftests => lib}/bpf/bpf_helpers.h (100%)
>  rename tools/{testing/selftests => lib}/bpf/bpf_tracing.h (100%)
^^^^^ nice! :)

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

* Re: [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  2019-10-03 20:16   ` Song Liu
@ 2019-10-03 20:28     ` Andrii Nakryiko
  2019-10-03 20:41       ` Song Liu
  0 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 20:28 UTC (permalink / raw)
  To: Song Liu
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 1:17 PM Song Liu <liu.song.a23@gmail.com> wrote:
>
> On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
> >
> > To allow adding a variadic BPF_CORE_READ macro with slightly different
> > syntax and semantics, define CORE_READ in CO-RE reloc tests, which is
> > a thin wrapper around low-level bpf_core_read() macro, which in turn is
> > just a wrapper around bpf_probe_read().
> >
> > Acked-by: John Fastabend <john.fastabend@gmail.com>
> > Acked-by: Song Liu <songliubraving@fb.com>
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > ---
> >  tools/testing/selftests/bpf/bpf_helpers.h      |  8 ++++----
> >  .../bpf/progs/test_core_reloc_arrays.c         | 10 ++++++----
> >  .../bpf/progs/test_core_reloc_flavors.c        |  8 +++++---
> >  .../selftests/bpf/progs/test_core_reloc_ints.c | 18 ++++++++++--------
> >  .../bpf/progs/test_core_reloc_kernel.c         |  6 ++++--
> >  .../selftests/bpf/progs/test_core_reloc_misc.c |  8 +++++---
> >  .../selftests/bpf/progs/test_core_reloc_mods.c | 18 ++++++++++--------
> >  .../bpf/progs/test_core_reloc_nesting.c        |  6 ++++--
> >  .../bpf/progs/test_core_reloc_primitives.c     | 12 +++++++-----
> >  .../bpf/progs/test_core_reloc_ptr_as_arr.c     |  4 +++-
> >  10 files changed, 58 insertions(+), 40 deletions(-)
> >
> > diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
> > index 7b75c38238e4..5210cc7d7c5c 100644
> > --- a/tools/testing/selftests/bpf/bpf_helpers.h
> > +++ b/tools/testing/selftests/bpf/bpf_helpers.h
> > @@ -483,7 +483,7 @@ struct pt_regs;
> >  #endif
> >
> >  /*
> > - * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset
> > + * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
> >   * relocation for source address using __builtin_preserve_access_index()
> >   * built-in, provided by Clang.
> >   *
> > @@ -498,8 +498,8 @@ struct pt_regs;
> >   * actual field offset, based on target kernel BTF type that matches original
> >   * (local) BTF, used to record relocation.
> >   */
> > -#define BPF_CORE_READ(dst, src)                                                \
> > -       bpf_probe_read((dst), sizeof(*(src)),                           \
> > -                      __builtin_preserve_access_index(src))
> > +#define bpf_core_read(dst, sz, src)                                        \
> > +       bpf_probe_read(dst, sz,                                             \
> > +                      (const void *)__builtin_preserve_access_index(src))
> >
> >  #endif
> > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > index bf67f0fdf743..58efe4944594 100644
> > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > @@ -31,6 +31,8 @@ struct core_reloc_arrays {
> >         struct core_reloc_arrays_substruct d[1][2];
> >  };
> >
> > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
>
> We are using sizeof(*dst) now, but I guess sizeof(*src) is better?
> And it should be sizeof(*(src)).

There is no clear winner and I've debated which one I should go with,
but I'm leaning towards using destination for the following reason.
Size of destination doesn't change, it's not relocatable and whatnot,
so this represents actual amount of storage we can safely read into
(if the program logic is correct, of course). On the other hand, size
of source might be different between kernels and we don't support
relocating it when it's passed into bpf_probe_read() as second arg.

There is at least one valid case where we should use destination size,
not source size: if we have an array of something (e.g, chars) and we
want to read only up to first N elements. In this case sizeof(*dst) is
what you really want: program will pre-allocate exact amount of data
and we'll do, say, char comm[16]; bpf_core_read(dst,
task_struct->comm). If task_struct->comm ever increases, this all will
work: we'll read first 16 characters only.

In almost every other case it doesn't matter whether its dst or src,
they have to match (i.e., we don't support relocation from int32 to
int64 right now).

>
> > +
> >  SEC("raw_tracepoint/sys_enter")
> >  int test_core_arrays(void *ctx)
> >  {
> > @@ -38,16 +40,16 @@ int test_core_arrays(void *ctx)
> >         struct core_reloc_arrays_output *out = (void *)&data.out;
> >
> >         /* in->a[2] */
> > -       if (BPF_CORE_READ(&out->a2, &in->a[2]))
> > +       if (CORE_READ(&out->a2, &in->a[2]))
> >                 return 1;
> >         /* in->b[1][2][3] */
> > -       if (BPF_CORE_READ(&out->b123, &in->b[1][2][3]))
> > +       if (CORE_READ(&out->b123, &in->b[1][2][3]))
> >                 return 1;
> >         /* in->c[1].c */
> > -       if (BPF_CORE_READ(&out->c1c, &in->c[1].c))
> > +       if (CORE_READ(&out->c1c, &in->c[1].c))
> >                 return 1;
> >         /* in->d[0][0].d */
> > -       if (BPF_CORE_READ(&out->d00d, &in->d[0][0].d))
> > +       if (CORE_READ(&out->d00d, &in->d[0][0].d))
> >                 return 1;
> >
> >         return 0;
> > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> > index 9fda73e87972..3348acc7e50b 100644
> > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_flavors.c
> > @@ -39,6 +39,8 @@ struct core_reloc_flavors___weird {
> >         };
> >  };
> >
> > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
> > +
> >  SEC("raw_tracepoint/sys_enter")
> >  int test_core_flavors(void *ctx)
> >  {
> > @@ -48,13 +50,13 @@ int test_core_flavors(void *ctx)
> >         struct core_reloc_flavors *out = (void *)&data.out;
> >
> >         /* read a using weird layout */
> > -       if (BPF_CORE_READ(&out->a, &in_weird->a))
> > +       if (CORE_READ(&out->a, &in_weird->a))
> >                 return 1;
> >         /* read b using reversed layout */
> > -       if (BPF_CORE_READ(&out->b, &in_rev->b))
> > +       if (CORE_READ(&out->b, &in_rev->b))
> >                 return 1;
> >         /* read c using original layout */
> > -       if (BPF_CORE_READ(&out->c, &in_orig->c))
> > +       if (CORE_READ(&out->c, &in_orig->c))
> >                 return 1;
> >
> >         return 0;
> > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> > index d99233c8008a..cfe16ede48dd 100644
> > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_ints.c
> > @@ -23,20 +23,22 @@ struct core_reloc_ints {
> >         int64_t         s64_field;
> >  };
> >
> > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
>
> ditto.
>
> > +
> >  SEC("raw_tracepoint/sys_enter")
> >  int test_core_ints(void *ctx)
> >  {
> >         struct core_reloc_ints *in = (void *)&data.in;
> >         struct core_reloc_ints *out = (void *)&data.out;
> >
> > -       if (BPF_CORE_READ(&out->u8_field, &in->u8_field) ||
> > -           BPF_CORE_READ(&out->s8_field, &in->s8_field) ||
> > -           BPF_CORE_READ(&out->u16_field, &in->u16_field) ||
> > -           BPF_CORE_READ(&out->s16_field, &in->s16_field) ||
> > -           BPF_CORE_READ(&out->u32_field, &in->u32_field) ||
> > -           BPF_CORE_READ(&out->s32_field, &in->s32_field) ||
> > -           BPF_CORE_READ(&out->u64_field, &in->u64_field) ||
> > -           BPF_CORE_READ(&out->s64_field, &in->s64_field))
> > +       if (CORE_READ(&out->u8_field, &in->u8_field) ||
> > +           CORE_READ(&out->s8_field, &in->s8_field) ||
> > +           CORE_READ(&out->u16_field, &in->u16_field) ||
> > +           CORE_READ(&out->s16_field, &in->s16_field) ||
> > +           CORE_READ(&out->u32_field, &in->u32_field) ||
> > +           CORE_READ(&out->s32_field, &in->s32_field) ||
> > +           CORE_READ(&out->u64_field, &in->u64_field) ||
> > +           CORE_READ(&out->s64_field, &in->s64_field))
> >                 return 1;
> >
> >         return 0;
> > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> > index 37e02aa3f0c8..e5308026cfda 100644
> > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_kernel.c
> > @@ -17,6 +17,8 @@ struct task_struct {
> >         int tgid;
> >  };
> >
> > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
> ditto again, and more below.
>
> Thanks,
> Song

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

* Re: [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers
  2019-10-02 21:50 ` [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers Andrii Nakryiko
@ 2019-10-03 20:35   ` Song Liu
  2019-10-03 21:25     ` Andrii Nakryiko
  0 siblings, 1 reply; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:35 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: bpf, Networking, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Kernel Team

On Wed, Oct 2, 2019 at 3:02 PM Andrii Nakryiko <andriin@fb.com> wrote:
>
> Add few macros simplifying BCC-like multi-level probe reads, while also
> emitting CO-RE relocations for each read.
>
> Acked-by: John Fastabend <john.fastabend@gmail.com>
> Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> ---
>  tools/lib/bpf/bpf_helpers.h | 143 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 143 insertions(+)
>
> diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
> index cb9d4d2224af..847dfd7125e4 100644
> --- a/tools/lib/bpf/bpf_helpers.h
> +++ b/tools/lib/bpf/bpf_helpers.h
> @@ -19,6 +19,10 @@
>   */
>  #define SEC(NAME) __attribute__((section(NAME), used))
>
> +#ifndef __always_inline
> +#define __always_inline __attribute__((always_inline))
> +#endif
> +
>  /* helper functions called from eBPF programs written in C */
>  static void *(*bpf_map_lookup_elem)(void *map, const void *key) =
>         (void *) BPF_FUNC_map_lookup_elem;
> @@ -312,4 +316,143 @@ struct bpf_map_def {
>         bpf_probe_read(dst, sz,                                             \
>                        (const void *)__builtin_preserve_access_index(src))
>
> +/*

nit: extra /*.

Well, I actually don't have a strong preference with this. Just to highlight
we are mixing two styles, which we already do in current bpf_helpers.h.

There are multiple other instances below.

Besides these.

Acked-by: Song Liu <songliubraving@fb.com>

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

* Re: [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  2019-10-03 20:28     ` Andrii Nakryiko
@ 2019-10-03 20:41       ` Song Liu
  2019-10-03 21:10         ` Andrii Nakryiko
  0 siblings, 1 reply; 26+ messages in thread
From: Song Liu @ 2019-10-03 20:41 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 1:29 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Thu, Oct 3, 2019 at 1:17 PM Song Liu <liu.song.a23@gmail.com> wrote:
> >
> > On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
> > >
> > > To allow adding a variadic BPF_CORE_READ macro with slightly different
> > > syntax and semantics, define CORE_READ in CO-RE reloc tests, which is
> > > a thin wrapper around low-level bpf_core_read() macro, which in turn is
> > > just a wrapper around bpf_probe_read().
> > >
> > > Acked-by: John Fastabend <john.fastabend@gmail.com>
> > > Acked-by: Song Liu <songliubraving@fb.com>
> > > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > > ---
> > >  tools/testing/selftests/bpf/bpf_helpers.h      |  8 ++++----
> > >  .../bpf/progs/test_core_reloc_arrays.c         | 10 ++++++----
> > >  .../bpf/progs/test_core_reloc_flavors.c        |  8 +++++---
> > >  .../selftests/bpf/progs/test_core_reloc_ints.c | 18 ++++++++++--------
> > >  .../bpf/progs/test_core_reloc_kernel.c         |  6 ++++--
> > >  .../selftests/bpf/progs/test_core_reloc_misc.c |  8 +++++---
> > >  .../selftests/bpf/progs/test_core_reloc_mods.c | 18 ++++++++++--------
> > >  .../bpf/progs/test_core_reloc_nesting.c        |  6 ++++--
> > >  .../bpf/progs/test_core_reloc_primitives.c     | 12 +++++++-----
> > >  .../bpf/progs/test_core_reloc_ptr_as_arr.c     |  4 +++-
> > >  10 files changed, 58 insertions(+), 40 deletions(-)
> > >
> > > diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
> > > index 7b75c38238e4..5210cc7d7c5c 100644
> > > --- a/tools/testing/selftests/bpf/bpf_helpers.h
> > > +++ b/tools/testing/selftests/bpf/bpf_helpers.h
> > > @@ -483,7 +483,7 @@ struct pt_regs;
> > >  #endif
> > >
> > >  /*
> > > - * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset
> > > + * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
> > >   * relocation for source address using __builtin_preserve_access_index()
> > >   * built-in, provided by Clang.
> > >   *
> > > @@ -498,8 +498,8 @@ struct pt_regs;
> > >   * actual field offset, based on target kernel BTF type that matches original
> > >   * (local) BTF, used to record relocation.
> > >   */
> > > -#define BPF_CORE_READ(dst, src)                                                \
> > > -       bpf_probe_read((dst), sizeof(*(src)),                           \
> > > -                      __builtin_preserve_access_index(src))
> > > +#define bpf_core_read(dst, sz, src)                                        \
> > > +       bpf_probe_read(dst, sz,                                             \
> > > +                      (const void *)__builtin_preserve_access_index(src))
> > >
> > >  #endif
> > > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > index bf67f0fdf743..58efe4944594 100644
> > > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > @@ -31,6 +31,8 @@ struct core_reloc_arrays {
> > >         struct core_reloc_arrays_substruct d[1][2];
> > >  };
> > >
> > > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
> >
> > We are using sizeof(*dst) now, but I guess sizeof(*src) is better?
> > And it should be sizeof(*(src)).
>
> There is no clear winner and I've debated which one I should go with,
> but I'm leaning towards using destination for the following reason.
> Size of destination doesn't change, it's not relocatable and whatnot,
> so this represents actual amount of storage we can safely read into
> (if the program logic is correct, of course). On the other hand, size
> of source might be different between kernels and we don't support
> relocating it when it's passed into bpf_probe_read() as second arg.
>
> There is at least one valid case where we should use destination size,
> not source size: if we have an array of something (e.g, chars) and we
> want to read only up to first N elements. In this case sizeof(*dst) is
> what you really want: program will pre-allocate exact amount of data
> and we'll do, say, char comm[16]; bpf_core_read(dst,
> task_struct->comm). If task_struct->comm ever increases, this all will
> work: we'll read first 16 characters only.
>
> In almost every other case it doesn't matter whether its dst or src,
> they have to match (i.e., we don't support relocation from int32 to
> int64 right now).

Hmm.. We could also reading multiple items into the same array, no?
Maybe we need another marco that takes size as an third parameter?

Also, for dst, it needs to be sizeof(*(dst)).

Thanks,
Song

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

* Re: [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro
  2019-10-03 20:41       ` Song Liu
@ 2019-10-03 21:10         ` Andrii Nakryiko
  0 siblings, 0 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 21:10 UTC (permalink / raw)
  To: Song Liu
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 1:42 PM Song Liu <liu.song.a23@gmail.com> wrote:
>
> On Thu, Oct 3, 2019 at 1:29 PM Andrii Nakryiko
> <andrii.nakryiko@gmail.com> wrote:
> >
> > On Thu, Oct 3, 2019 at 1:17 PM Song Liu <liu.song.a23@gmail.com> wrote:
> > >
> > > On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
> > > >
> > > > To allow adding a variadic BPF_CORE_READ macro with slightly different
> > > > syntax and semantics, define CORE_READ in CO-RE reloc tests, which is
> > > > a thin wrapper around low-level bpf_core_read() macro, which in turn is
> > > > just a wrapper around bpf_probe_read().
> > > >
> > > > Acked-by: John Fastabend <john.fastabend@gmail.com>
> > > > Acked-by: Song Liu <songliubraving@fb.com>
> > > > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > > > ---
> > > >  tools/testing/selftests/bpf/bpf_helpers.h      |  8 ++++----
> > > >  .../bpf/progs/test_core_reloc_arrays.c         | 10 ++++++----
> > > >  .../bpf/progs/test_core_reloc_flavors.c        |  8 +++++---
> > > >  .../selftests/bpf/progs/test_core_reloc_ints.c | 18 ++++++++++--------
> > > >  .../bpf/progs/test_core_reloc_kernel.c         |  6 ++++--
> > > >  .../selftests/bpf/progs/test_core_reloc_misc.c |  8 +++++---
> > > >  .../selftests/bpf/progs/test_core_reloc_mods.c | 18 ++++++++++--------
> > > >  .../bpf/progs/test_core_reloc_nesting.c        |  6 ++++--
> > > >  .../bpf/progs/test_core_reloc_primitives.c     | 12 +++++++-----
> > > >  .../bpf/progs/test_core_reloc_ptr_as_arr.c     |  4 +++-
> > > >  10 files changed, 58 insertions(+), 40 deletions(-)
> > > >
> > > > diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
> > > > index 7b75c38238e4..5210cc7d7c5c 100644
> > > > --- a/tools/testing/selftests/bpf/bpf_helpers.h
> > > > +++ b/tools/testing/selftests/bpf/bpf_helpers.h
> > > > @@ -483,7 +483,7 @@ struct pt_regs;
> > > >  #endif
> > > >
> > > >  /*
> > > > - * BPF_CORE_READ abstracts away bpf_probe_read() call and captures offset
> > > > + * bpf_core_read() abstracts away bpf_probe_read() call and captures offset
> > > >   * relocation for source address using __builtin_preserve_access_index()
> > > >   * built-in, provided by Clang.
> > > >   *
> > > > @@ -498,8 +498,8 @@ struct pt_regs;
> > > >   * actual field offset, based on target kernel BTF type that matches original
> > > >   * (local) BTF, used to record relocation.
> > > >   */
> > > > -#define BPF_CORE_READ(dst, src)                                                \
> > > > -       bpf_probe_read((dst), sizeof(*(src)),                           \
> > > > -                      __builtin_preserve_access_index(src))
> > > > +#define bpf_core_read(dst, sz, src)                                        \
> > > > +       bpf_probe_read(dst, sz,                                             \
> > > > +                      (const void *)__builtin_preserve_access_index(src))
> > > >
> > > >  #endif
> > > > diff --git a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > > index bf67f0fdf743..58efe4944594 100644
> > > > --- a/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > > +++ b/tools/testing/selftests/bpf/progs/test_core_reloc_arrays.c
> > > > @@ -31,6 +31,8 @@ struct core_reloc_arrays {
> > > >         struct core_reloc_arrays_substruct d[1][2];
> > > >  };
> > > >
> > > > +#define CORE_READ(dst, src) bpf_core_read(dst, sizeof(*dst), src)
> > >
> > > We are using sizeof(*dst) now, but I guess sizeof(*src) is better?
> > > And it should be sizeof(*(src)).
> >
> > There is no clear winner and I've debated which one I should go with,
> > but I'm leaning towards using destination for the following reason.
> > Size of destination doesn't change, it's not relocatable and whatnot,
> > so this represents actual amount of storage we can safely read into
> > (if the program logic is correct, of course). On the other hand, size
> > of source might be different between kernels and we don't support
> > relocating it when it's passed into bpf_probe_read() as second arg.
> >
> > There is at least one valid case where we should use destination size,
> > not source size: if we have an array of something (e.g, chars) and we
> > want to read only up to first N elements. In this case sizeof(*dst) is
> > what you really want: program will pre-allocate exact amount of data
> > and we'll do, say, char comm[16]; bpf_core_read(dst,
> > task_struct->comm). If task_struct->comm ever increases, this all will
> > work: we'll read first 16 characters only.
> >
> > In almost every other case it doesn't matter whether its dst or src,
> > they have to match (i.e., we don't support relocation from int32 to
> > int64 right now).
>
> Hmm.. We could also reading multiple items into the same array, no?

Yeah, absolutely, there are cases in which BPF_CORE_READ won't work,
unfortunately. That's why it was an internal debate, because there is
no perfect answer :)

> Maybe we need another marco that takes size as an third parameter?

So my thinking for cases that are not compatible with BPF_CORE_READ
intended use cases was that users will just do bpf_core_read(), which
accepts same params as bpf_probe_read(), so they can do whatever they
need to do.


>
> Also, for dst, it needs to be sizeof(*(dst)).

You mean extra () around dst? Sure, will add.

>
> Thanks,
> Song

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

* Re: [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h
  2019-10-03 20:08   ` Song Liu
@ 2019-10-03 21:22     ` Andrii Nakryiko
  0 siblings, 0 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 21:22 UTC (permalink / raw)
  To: Song Liu
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 1:09 PM Song Liu <liu.song.a23@gmail.com> wrote:
>
> On Wed, Oct 2, 2019 at 3:01 PM Andrii Nakryiko <andriin@fb.com> wrote:
> >
> > Split off few legacy things from bpf_helpers.h into separate
> > bpf_legacy.h file:
> > - load_{byte|half|word};
> > - remove extra inner_idx and numa_node fields from bpf_map_def and
> >   introduce bpf_map_def_legacy for use in samples;
> > - move BPF_ANNOTATE_KV_PAIR into bpf_legacy.h.
> >
> > Adjust samples and selftests accordingly by either including
> > bpf_legacy.h and using bpf_map_def_legacy, or switching to BTF-defined
> > maps altogether.
> >
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
>
> Acked-by: Song Liu <songliubraving@fb.com>
>
> with a nit below
>
> > ---
> >  samples/bpf/hbm_kern.h                        | 28 +++++++------
> >  samples/bpf/map_perf_test_kern.c              | 23 +++++------
> >  samples/bpf/parse_ldabs.c                     |  1 +
> >  samples/bpf/sockex1_kern.c                    |  1 +
> >  samples/bpf/sockex2_kern.c                    |  1 +
> >  samples/bpf/sockex3_kern.c                    |  1 +
> >  samples/bpf/tcbpf1_kern.c                     |  1 +
> >  samples/bpf/test_map_in_map_kern.c            | 15 +++----
> >  tools/testing/selftests/bpf/bpf_helpers.h     | 24 +-----------
> >  tools/testing/selftests/bpf/bpf_legacy.h      | 39 +++++++++++++++++++
> >  .../testing/selftests/bpf/progs/sockopt_sk.c  | 13 +++----
> >  tools/testing/selftests/bpf/progs/tcp_rtt.c   | 13 +++----
> >  .../selftests/bpf/progs/test_btf_haskv.c      |  1 +
> >  .../selftests/bpf/progs/test_btf_newkv.c      |  1 +
> >  14 files changed, 92 insertions(+), 70 deletions(-)
> >  create mode 100644 tools/testing/selftests/bpf/bpf_legacy.h
> >
> > diff --git a/samples/bpf/hbm_kern.h b/samples/bpf/hbm_kern.h
> > index aa207a2eebbd..91880a0e9c2f 100644
> > --- a/samples/bpf/hbm_kern.h
> > +++ b/samples/bpf/hbm_kern.h
> > @@ -24,6 +24,7 @@
> >  #include <net/inet_ecn.h>
> >  #include "bpf_endian.h"
> >  #include "bpf_helpers.h"
> > +#include "bpf_legacy.h"
>
> nit: I guess we don't need bpf_legacy.h here?

You are right, I converted maps to BTF-defined ones, dropping bpf_legacy.h.

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

* Re: [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers
  2019-10-03 20:35   ` Song Liu
@ 2019-10-03 21:25     ` Andrii Nakryiko
  0 siblings, 0 replies; 26+ messages in thread
From: Andrii Nakryiko @ 2019-10-03 21:25 UTC (permalink / raw)
  To: Song Liu
  Cc: Andrii Nakryiko, bpf, Networking, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team

On Thu, Oct 3, 2019 at 1:35 PM Song Liu <liu.song.a23@gmail.com> wrote:
>
> On Wed, Oct 2, 2019 at 3:02 PM Andrii Nakryiko <andriin@fb.com> wrote:
> >
> > Add few macros simplifying BCC-like multi-level probe reads, while also
> > emitting CO-RE relocations for each read.
> >
> > Acked-by: John Fastabend <john.fastabend@gmail.com>
> > Signed-off-by: Andrii Nakryiko <andriin@fb.com>
> > ---
> >  tools/lib/bpf/bpf_helpers.h | 143 ++++++++++++++++++++++++++++++++++++
> >  1 file changed, 143 insertions(+)
> >
> > diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
> > index cb9d4d2224af..847dfd7125e4 100644
> > --- a/tools/lib/bpf/bpf_helpers.h
> > +++ b/tools/lib/bpf/bpf_helpers.h
> > @@ -19,6 +19,10 @@
> >   */
> >  #define SEC(NAME) __attribute__((section(NAME), used))
> >
> > +#ifndef __always_inline
> > +#define __always_inline __attribute__((always_inline))
> > +#endif
> > +
> >  /* helper functions called from eBPF programs written in C */
> >  static void *(*bpf_map_lookup_elem)(void *map, const void *key) =
> >         (void *) BPF_FUNC_map_lookup_elem;
> > @@ -312,4 +316,143 @@ struct bpf_map_def {
> >         bpf_probe_read(dst, sz,                                             \
> >                        (const void *)__builtin_preserve_access_index(src))
> >
> > +/*
>
> nit: extra /*.
>
> Well, I actually don't have a strong preference with this. Just to highlight
> we are mixing two styles, which we already do in current bpf_helpers.h.

I made it consistent, thanks.

>
> There are multiple other instances below.
>
> Besides these.
>
> Acked-by: Song Liu <songliubraving@fb.com>

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

end of thread, other threads:[~2019-10-03 21:25 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-02 21:50 [PATCH v2 bpf-next 0/7] Move bpf_helpers and add BPF_CORE_READ macros Andrii Nakryiko
2019-10-02 21:50 ` [PATCH v2 bpf-next 1/7] selftests/bpf: undo GCC-specific bpf_helpers.h changes Andrii Nakryiko
2019-10-02 21:50 ` [PATCH v2 bpf-next 2/7] selftests/bpf: samples/bpf: split off legacy stuff from bpf_helpers.h Andrii Nakryiko
2019-10-03  7:35   ` Toke Høiland-Jørgensen
2019-10-03 16:20     ` Andrii Nakryiko
2019-10-03 16:27       ` Toke Høiland-Jørgensen
2019-10-03 17:31   ` John Fastabend
2019-10-03 20:08   ` Song Liu
2019-10-03 21:22     ` Andrii Nakryiko
2019-10-02 21:50 ` [PATCH v2 bpf-next 3/7] selftests/bpf: adjust CO-RE reloc tests for new bpf_core_read() macro Andrii Nakryiko
2019-10-03 20:16   ` Song Liu
2019-10-03 20:28     ` Andrii Nakryiko
2019-10-03 20:41       ` Song Liu
2019-10-03 21:10         ` Andrii Nakryiko
2019-10-02 21:50 ` [PATCH v2 bpf-next 4/7] selftests/bpf: split off tracing-only helpers into bpf_tracing.h Andrii Nakryiko
2019-10-03  7:35   ` Toke Høiland-Jørgensen
2019-10-03 16:22     ` Andrii Nakryiko
2019-10-03 17:21       ` Toke Høiland-Jørgensen
2019-10-03 17:33   ` John Fastabend
2019-10-03 20:18     ` Song Liu
2019-10-02 21:50 ` [PATCH v2 bpf-next 5/7] libbpf: move bpf_{helpers,endian,tracing}.h into libbpf Andrii Nakryiko
2019-10-03 20:22   ` Song Liu
2019-10-02 21:50 ` [PATCH v2 bpf-next 6/7] libbpf: add BPF_CORE_READ/BPF_CORE_READ_INTO helpers Andrii Nakryiko
2019-10-03 20:35   ` Song Liu
2019-10-03 21:25     ` Andrii Nakryiko
2019-10-02 21:50 ` [PATCH v2 bpf-next 7/7] selftests/bpf: add BPF_CORE_READ and BPF_CORE_READ_STR_INTO macro tests Andrii Nakryiko

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).