@@ -737,6 +737,19 @@ static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,
BPF_DISPATCHER_FUNC(bpf_dispatcher_xdp));
}
+static __always_inline u32 bpf_prog_run_xdp_trace(const struct bpf_prog *prog,
+ struct xdp_buff *xdp)
+{
+ /* Caller needs to hold rcu_read_lock() (!), otherwise program
+ * can be released while still running, or map elements could be
+ * freed early while still having concurrent users. XDP fastpath
+ * already takes rcu_read_lock() when fetching the program, so
+ * it's not necessary here anymore.
+ */
+ return __BPF_PROG_RUN(prog, xdp,
+ BPF_DISPATCHER_FUNC(bpf_dispatcher_xdp));
+}
+
void bpf_prog_change_xdp(struct bpf_prog *prev_prog, struct bpf_prog *prog);
static inline u32 bpf_prog_insn_size(const struct bpf_prog *prog)
@@ -375,6 +375,9 @@ enum {
*/
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
+/* Flags for BPF_PROG_TEST_RUN. */
+#define BPF_F_TEST_ENABLE_TRACE (1U << 0)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
@@ -511,6 +514,7 @@ union bpf_attr {
*/
__aligned_u64 ctx_in;
__aligned_u64 ctx_out;
+ __u32 flags;
} test;
struct { /* anonymous struct used by BPF_*_GET_*_ID */
@@ -2680,7 +2680,7 @@ static int bpf_prog_query(const union bpf_attr *attr,
return cgroup_bpf_prog_query(attr, uattr);
}
-#define BPF_PROG_TEST_RUN_LAST_FIELD test.ctx_out
+#define BPF_PROG_TEST_RUN_LAST_FIELD test.flags
static int bpf_prog_test_run(const union bpf_attr *attr,
union bpf_attr __user *uattr)
@@ -16,7 +16,7 @@
#include <trace/events/bpf_test_run.h>
static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
- u32 *retval, u32 *time, bool xdp)
+ u32 *retval, u32 *time, bool xdp, bool trace)
{
struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = { NULL };
enum bpf_cgroup_storage_type stype;
@@ -43,10 +43,14 @@ static int bpf_test_run(struct bpf_prog *prog, void *ctx, u32 repeat,
for (i = 0; i < repeat; i++) {
bpf_cgroup_storage_set(storage);
- if (xdp)
- *retval = bpf_prog_run_xdp(prog, ctx);
- else
+ if (xdp) {
+ if (trace)
+ *retval = bpf_prog_run_xdp_trace(prog, ctx);
+ else
+ *retval = bpf_prog_run_xdp(prog, ctx);
+ } else {
*retval = BPF_PROG_RUN(prog, ctx);
+ }
if (signal_pending(current)) {
ret = -EINTR;
@@ -431,7 +435,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
ret = convert___skb_to_skb(skb, ctx);
if (ret)
goto out;
- ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
+ ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false, false);
if (ret)
goto out;
if (!is_l2) {
@@ -468,6 +472,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
{
u32 size = kattr->test.data_size_in;
u32 repeat = kattr->test.repeat;
+ bool trace = kattr->test.flags & BPF_F_TEST_ENABLE_TRACE;
struct netdev_rx_queue *rxqueue;
struct xdp_buff xdp = {};
u32 retval, duration;
@@ -489,7 +494,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
xdp.rxq = &rxqueue->xdp_rxq;
bpf_prog_change_xdp(NULL, prog);
- ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true);
+ ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true, trace);
if (ret)
goto out;
if (xdp.data != data + XDP_PACKET_HEADROOM + NET_IP_ALIGN ||
@@ -375,6 +375,9 @@ enum {
*/
#define BPF_F_QUERY_EFFECTIVE (1U << 0)
+/* Flags for BPF_PROG_TEST_RUN. */
+#define BPF_F_TEST_ENABLE_TRACE (1U << 0)
+
enum bpf_stack_build_id_status {
/* user space need an empty entry to identify end of a trace */
BPF_STACK_BUILD_ID_EMPTY = 0,
@@ -511,6 +514,7 @@ union bpf_attr {
*/
__aligned_u64 ctx_in;
__aligned_u64 ctx_out;
+ __u32 flags;
} test;
struct { /* anonymous struct used by BPF_*_GET_*_ID */
This patch adds a flag to the existing BPF_PROG_TEST_RUN API, which will allow tracing for XDP programs. Signed-off-by: Eelco Chaudron <echaudro@redhat.com> --- include/linux/filter.h | 13 +++++++++++++ include/uapi/linux/bpf.h | 4 ++++ kernel/bpf/syscall.c | 2 +- net/bpf/test_run.c | 17 +++++++++++------ tools/include/uapi/linux/bpf.h | 4 ++++ 5 files changed, 33 insertions(+), 7 deletions(-)