[PATCH v5] bpf: support new commands BPF_MAP_*_BATCH

Paul Chaignon paul.chaignon at gmail.com
Sat Apr 4 18:11:02 UTC 2020


* xlat/bpf_commands.in (BPF_MAP_LOOKUP_BATCH): New constant introduced
by Linux commit v5.6-rc1~151^2~46^2~23^2~7.
(BPF_MAP_LOOKUP_AND_DELETE_BATCH): New constant introduced by Linux
commit v5.6-rc1~151^2~46^2~23^2~4.
(BPF_MAP_UPDATE_BATCH, BPF_MAP_DELETE_BATCH): New constants introduced
by Linux commit v5.6-rc1~151^2~46^2~23^2~6.
* bpf.c (BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_BATCH),
BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_BATCH),
BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_BATCH)): Decode the new commands.
(decode_BPF_MAP_LOOKUP_AND_DELETE_BATCH): New macro.
(SYS_FUNC(bpf)): Decode the new commands.
* bpf_attr.h (BPF_MAP_LOOKUP_BATCH_struct,
BPF_MAP_LOOKUP_AND_DELETE_BATCH_struct, BPF_MAP_UPDATE_BATCH_struct,
BPF_MAP_DELETE_BATCH_struct): New structs introduced by Linux commit
v5.6-rc1~151^2~46^2~23^2~7.
(BPF_MAP_LOOKUP_BATCH_struct_size,
BPF_MAP_LOOKUP_AND_DELETE_BATCH_struct_size,
BPF_MAP_UPDATE_BATCH_struct_size, BPF_MAP_DELETE_BATCH_struct_size): New
macros.
* NEWS: Mention this.
* tests/bpf.c (BPF_MAP_LOOKUP_BATCH_checks, BPF_MAP_UPDATE_BATCH_checks,
BPF_MAP_DELETE_BATCH_checks): Tests for the new commands.

Signed-off-by: Paul Chaignon <paul.chaignon at gmail.com>
---
Changelogs:
  Changes in v5:
  - Display "batch=" on syscall exit.
  Changes in v4:
  - Fix printing of extra data and closing brackets.
  - Print name of "batch" structure.
  Changes in v3:
  - Add tests for BPF_MAP_UPDATE_BATCH and BPF_MAP_DELETE_BATCH.
  - Do not print unused fields in_batch and out_batch.
  - Print count on entering and exiting.
  - Fix printing of flags.
  Changes in v2:
  - Add ATTRIBUTE_ALIGNED(8) to uint64_t attributes.
  - Rebase on master.

 NEWS                 |  3 ++
 bpf.c                | 88 ++++++++++++++++++++++++++++++++++++++++++++
 bpf_attr.h           | 24 ++++++++++++
 tests/bpf.c          | 75 +++++++++++++++++++++++++++++++++++++
 xlat/bpf_commands.in |  4 ++
 5 files changed, 194 insertions(+)

diff --git a/NEWS b/NEWS
index 6e6dda34..b667bd04 100644
--- a/NEWS
+++ b/NEWS
@@ -30,6 +30,9 @@ Noteworthy changes in release ?.? (????-??-??)
   * Implemented decoding of openat2 and pidfd_getfd syscalls.
   * Enhanced io_uring_register, prctl, sched_getattr, and sched_setattr syscall
     decoding.
+  * Implemented decoding of BPF_MAP_LOOKUP_BATCH,
+    BPF_MAP_LOOKUP_AND_DELETE_BATCH, BPF_MAP_UPDATE_BATCH, and
+    BPF_MAP_DELETE_BATCH bpf syscall commands.
   * Enhanced decoding of BPF_MAP_CREATE and BPF_PROG_ATTACH bpf syscall
     commands.
   * Enhanced decoding of RTC_VL_READ ioctl command.
diff --git a/bpf.c b/bpf.c
index d666a423..f55a19b4 100644
--- a/bpf.c
+++ b/bpf.c
@@ -954,6 +954,90 @@ BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY)
 }
 END_BPF_CMD_DECODER(RVAL_DECODED)
 
+BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_BATCH)
+{
+	unsigned long count;
+
+	if (entering(tcp)) {
+		set_tcb_priv_ulong(tcp, attr.count);
+
+		PRINT_FIELD_ADDR64("{batch={", attr, in_batch);
+		PRINT_FIELD_ADDR64(", ", attr, out_batch);
+		PRINT_FIELD_ADDR64(", ", attr, keys);
+		PRINT_FIELD_ADDR64(", ", attr, values);
+		PRINT_FIELD_U(", ", attr, count);
+		PRINT_FIELD_FD(", ", attr, map_fd, tcp);
+		PRINT_FIELD_FLAGS(", ", attr, elem_flags,
+				  bpf_map_lookup_elem_flags, "BPF_???");
+		PRINT_FIELD_X(", ", attr, flags);
+
+		tprintf("}");
+	} else {
+		count = get_tcb_priv_ulong(tcp);
+		if (count != attr.count) {
+			PRINT_FIELD_U("=> batch={", attr, count);
+			tprintf("}");
+		}
+		return RVAL_DECODED;
+	}
+}
+END_BPF_CMD_DECODER(0)
+
+#define decode_BPF_MAP_LOOKUP_AND_DELETE_BATCH decode_BPF_MAP_LOOKUP_BATCH
+
+BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_BATCH)
+{
+	unsigned long count;
+
+	if (entering(tcp)) {
+		set_tcb_priv_ulong(tcp, attr.count);
+
+		PRINT_FIELD_ADDR64("{batch={", attr, keys);
+		PRINT_FIELD_ADDR64(", ", attr, values);
+		PRINT_FIELD_U(", ", attr, count);
+		PRINT_FIELD_FD(", ", attr, map_fd, tcp);
+		PRINT_FIELD_FLAGS(", ", attr, elem_flags,
+				  bpf_map_lookup_elem_flags, "BPF_???");
+		PRINT_FIELD_X(", ", attr, flags);
+
+		tprintf("}");
+	} else {
+		count = get_tcb_priv_ulong(tcp);
+		if (count != attr.count) {
+			PRINT_FIELD_U("=> batch={", attr, count);
+			tprintf("}");
+		}
+		return RVAL_DECODED;
+	}
+}
+END_BPF_CMD_DECODER(0)
+
+BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_BATCH)
+{
+	unsigned long count;
+
+	if (entering(tcp)) {
+		set_tcb_priv_ulong(tcp, attr.count);
+
+		PRINT_FIELD_ADDR64("{batch={", attr, keys);
+		PRINT_FIELD_U(", ", attr, count);
+		PRINT_FIELD_FD(", ", attr, map_fd, tcp);
+		PRINT_FIELD_FLAGS(", ", attr, elem_flags,
+				  bpf_map_lookup_elem_flags, "BPF_???");
+		PRINT_FIELD_X(", ", attr, flags);
+
+		tprintf("}");
+	} else {
+		count = get_tcb_priv_ulong(tcp);
+		if (count != attr.count) {
+			PRINT_FIELD_U("=> batch={", attr, count);
+			tprintf("}");
+		}
+		return RVAL_DECODED;
+	}
+}
+END_BPF_CMD_DECODER(0)
+
 SYS_FUNC(bpf)
 {
 	static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
@@ -981,6 +1065,10 @@ SYS_FUNC(bpf)
 		BPF_CMD_ENTRY(BPF_MAP_LOOKUP_AND_DELETE_ELEM),
 		BPF_CMD_ENTRY(BPF_MAP_FREEZE),
 		BPF_CMD_ENTRY(BPF_BTF_GET_NEXT_ID),
+		BPF_CMD_ENTRY(BPF_MAP_LOOKUP_BATCH),
+		BPF_CMD_ENTRY(BPF_MAP_LOOKUP_AND_DELETE_BATCH),
+		BPF_CMD_ENTRY(BPF_MAP_UPDATE_BATCH),
+		BPF_CMD_ENTRY(BPF_MAP_DELETE_BATCH),
 	};
 
 	const unsigned int cmd = tcp->u_arg[0];
diff --git a/bpf_attr.h b/bpf_attr.h
index f348c169..6b66fb06 100644
--- a/bpf_attr.h
+++ b/bpf_attr.h
@@ -361,4 +361,28 @@ struct bpf_prog_info_struct {
 	sizeof(struct bpf_prog_info_struct)
 # define expected_bpf_prog_info_struct_size 208
 
+struct BPF_MAP_LOOKUP_BATCH_struct /* batch */ {
+	uint64_t ATTRIBUTE_ALIGNED(8) in_batch;
+	uint64_t ATTRIBUTE_ALIGNED(8) out_batch;
+	uint64_t ATTRIBUTE_ALIGNED(8) keys;
+	uint64_t ATTRIBUTE_ALIGNED(8) values;
+	uint32_t count;
+	uint32_t map_fd;
+	uint64_t ATTRIBUTE_ALIGNED(8) elem_flags;
+	uint64_t ATTRIBUTE_ALIGNED(8) flags;
+};
+
+# define BPF_MAP_LOOKUP_BATCH_struct_size \
+	sizeof(struct BPF_MAP_LOOKUP_BATCH_struct)
+# define expected_BPF_MAP_LOOKUP_BATCH_struct_size 56
+
+# define BPF_MAP_LOOKUP_AND_DELETE_BATCH_struct BPF_MAP_LOOKUP_BATCH_struct
+# define BPF_MAP_LOOKUP_AND_DELETE_BATCH_struct_size BPF_MAP_LOOKUP_BATCH_struct_size
+
+# define BPF_MAP_UPDATE_BATCH_struct BPF_MAP_LOOKUP_BATCH_struct
+# define BPF_MAP_UPDATE_BATCH_struct_size BPF_MAP_LOOKUP_BATCH_struct_size
+
+# define BPF_MAP_DELETE_BATCH_struct BPF_MAP_LOOKUP_BATCH_struct
+# define BPF_MAP_DELETE_BATCH_struct_size BPF_MAP_LOOKUP_BATCH_struct_size
+
 #endif /* !STRACE_BPF_ATTR_H */
diff --git a/tests/bpf.c b/tests/bpf.c
index 43872cd7..fc000242 100644
--- a/tests/bpf.c
+++ b/tests/bpf.c
@@ -80,6 +80,9 @@ union bpf_attr_data {
 	BPF_ATTR_DATA_FIELD(BPF_BTF_GET_FD_BY_ID);
 	BPF_ATTR_DATA_FIELD(BPF_TASK_FD_QUERY);
 	BPF_ATTR_DATA_FIELD(BPF_MAP_FREEZE);
+	BPF_ATTR_DATA_FIELD(BPF_MAP_LOOKUP_BATCH);
+	BPF_ATTR_DATA_FIELD(BPF_MAP_UPDATE_BATCH);
+	BPF_ATTR_DATA_FIELD(BPF_MAP_DELETE_BATCH);
 	char char_data[256];
 };
 
@@ -1316,6 +1319,75 @@ static const struct bpf_attr_check BPF_TASK_FD_QUERY_checks[] = {
 	}
 };
 
+static const struct bpf_attr_check BPF_MAP_LOOKUP_BATCH_checks[] = {
+	{
+		.data = { .BPF_MAP_LOOKUP_BATCH_data = { .map_fd = -1 } },
+		.size = offsetofend(struct BPF_MAP_LOOKUP_BATCH_struct, map_fd ),
+		.str = "batch={in_batch=NULL, out_batch=NULL, keys=NULL"
+		       ", values=NULL, count=0, map_fd=-1, elem_flags=BPF_ANY"
+		       ", flags=0}"
+	},
+	{
+		.data = { .BPF_MAP_LOOKUP_BATCH_data = {
+			.in_batch = 0xfacefeed,
+			.out_batch = 0xbadc0ded,
+			.keys = 0xdeadf00d,
+			.values = 0xfffffffe,
+			.count = 3,
+			.map_fd = -1,
+			.elem_flags = 4,
+			.flags = 4
+		} },
+		.size = offsetofend(struct BPF_MAP_LOOKUP_BATCH_struct, flags),
+		.str = "batch={in_batch=0xfacefeed, out_batch=0xbadc0ded"
+		       ", keys=0xdeadf00d, values=0xfffffffe, count=3"
+		       ", map_fd=-1, elem_flags=BPF_F_LOCK, flags=0x4}"
+	}
+};
+
+static const struct bpf_attr_check BPF_MAP_UPDATE_BATCH_checks[] = {
+	{
+		.data = { .BPF_MAP_UPDATE_BATCH_data = { .map_fd = -1 } },
+		.size = offsetofend(struct BPF_MAP_UPDATE_BATCH_struct, map_fd ),
+		.str = "batch={keys=NULL, values=NULL, count=0, map_fd=-1"
+		       ", elem_flags=BPF_ANY, flags=0}"
+	},
+	{
+		.data = { .BPF_MAP_UPDATE_BATCH_data = {
+			.keys = 0xdeadf00d,
+			.values = 0xfffffffe,
+			.count = 3,
+			.map_fd = -1,
+			.elem_flags = 4,
+			.flags = 4
+		} },
+		.size = offsetofend(struct BPF_MAP_UPDATE_BATCH_struct, flags),
+		.str = "batch={keys=0xdeadf00d, values=0xfffffffe, count=3"
+		       ", map_fd=-1, elem_flags=BPF_F_LOCK, flags=0x4}"
+	}
+};
+
+static const struct bpf_attr_check BPF_MAP_DELETE_BATCH_checks[] = {
+	{
+		.data = { .BPF_MAP_DELETE_BATCH_data = { .map_fd = -1 } },
+		.size = offsetofend(struct BPF_MAP_DELETE_BATCH_struct, map_fd ),
+		.str = "batch={keys=NULL, count=0, map_fd=-1"
+		       ", elem_flags=BPF_ANY, flags=0}"
+	},
+	{
+		.data = { .BPF_MAP_DELETE_BATCH_data = {
+			.keys = 0xdeadf00d,
+			.count = 3,
+			.map_fd = -1,
+			.elem_flags = 4,
+			.flags = 4
+		} },
+		.size = offsetofend(struct BPF_MAP_DELETE_BATCH_struct, flags),
+		.str = "batch={keys=0xdeadf00d, count=3, map_fd=-1"
+		       ", elem_flags=BPF_F_LOCK, flags=0x4}"
+	}
+};
+
 
 #define CHK(cmd_) \
 	{ \
@@ -1352,6 +1424,9 @@ main(void)
 		CHK(BPF_MAP_LOOKUP_AND_DELETE_ELEM),
 		CHK(BPF_MAP_FREEZE),
 		CHK(BPF_BTF_GET_NEXT_ID),
+		CHK(BPF_MAP_LOOKUP_BATCH),
+		CHK(BPF_MAP_UPDATE_BATCH),
+		CHK(BPF_MAP_DELETE_BATCH),
 	};
 
 	page_size = get_page_size();
diff --git a/xlat/bpf_commands.in b/xlat/bpf_commands.in
index 63166fb5..2b95264b 100644
--- a/xlat/bpf_commands.in
+++ b/xlat/bpf_commands.in
@@ -23,3 +23,7 @@ BPF_TASK_FD_QUERY 20
 BPF_MAP_LOOKUP_AND_DELETE_ELEM 21
 BPF_MAP_FREEZE 22
 BPF_BTF_GET_NEXT_ID 23
+BPF_MAP_LOOKUP_BATCH 24
+BPF_MAP_LOOKUP_AND_DELETE_BATCH 25
+BPF_MAP_UPDATE_BATCH 26
+BPF_MAP_DELETE_BATCH 27
-- 
2.20.1



More information about the Strace-devel mailing list