Skip to content

Commit a67edbf

Browse files
borkmanndavem330
authored andcommitted
bpf: add initial bpf tracepoints
This work adds a number of tracepoints to paths that are either considered slow-path or exception-like states, where monitoring or inspecting them would be desirable. For bpf(2) syscall, tracepoints have been placed for main commands when they succeed. In XDP case, tracepoint is for exceptions, that is, f.e. on abnormal BPF program exit such as unknown or XDP_ABORTED return code, or when error occurs during XDP_TX action and the packet could not be forwarded. Both have been split into separate event headers, and can be further extended. Worst case, if they unexpectedly should get into our way in future, they can also removed [1]. Of course, these tracepoints (like any other) can be analyzed by eBPF itself, etc. Example output: # ./perf record -a -e bpf:* sleep 10 # ./perf script sock_example 6197 [005] 283.980322: bpf:bpf_map_create: map type=ARRAY ufd=4 key=4 val=8 max=256 flags=0 sock_example 6197 [005] 283.980721: bpf:bpf_prog_load: prog=a5ea8fa30ea6849c type=SOCKET_FILTER ufd=5 sock_example 6197 [005] 283.988423: bpf:bpf_prog_get_type: prog=a5ea8fa30ea6849c type=SOCKET_FILTER sock_example 6197 [005] 283.988443: bpf:bpf_map_lookup_elem: map type=ARRAY ufd=4 key=[06 00 00 00] val=[00 00 00 00 00 00 00 00] [...] sock_example 6197 [005] 288.990868: bpf:bpf_map_lookup_elem: map type=ARRAY ufd=4 key=[01 00 00 00] val=[14 00 00 00 00 00 00 00] swapper 0 [005] 289.338243: bpf:bpf_prog_put_rcu: prog=a5ea8fa30ea6849c type=SOCKET_FILTER [1] https://lwn.net/Articles/705270/ Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0fe0559 commit a67edbf

File tree

11 files changed

+483
-15
lines changed

11 files changed

+483
-15
lines changed

drivers/net/ethernet/mellanox/mlx4/en_rx.c

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include <net/busy_poll.h>
3535
#include <linux/bpf.h>
36+
#include <linux/bpf_trace.h>
3637
#include <linux/mlx4/cq.h>
3738
#include <linux/slab.h>
3839
#include <linux/mlx4/qp.h>
@@ -926,10 +927,12 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
926927
length, cq->ring,
927928
&doorbell_pending)))
928929
goto consumed;
930+
trace_xdp_exception(dev, xdp_prog, act);
929931
goto xdp_drop_no_cnt; /* Drop on xmit failure */
930932
default:
931933
bpf_warn_invalid_xdp_action(act);
932934
case XDP_ABORTED:
935+
trace_xdp_exception(dev, xdp_prog, act);
933936
case XDP_DROP:
934937
ring->xdp_drop++;
935938
xdp_drop_no_cnt:

drivers/net/ethernet/mellanox/mlx5/core/en_rx.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <linux/ip.h>
3434
#include <linux/ipv6.h>
3535
#include <linux/tcp.h>
36+
#include <linux/bpf_trace.h>
3637
#include <net/busy_poll.h>
3738
#include "en.h"
3839
#include "en_tc.h"
@@ -640,7 +641,7 @@ static inline void mlx5e_xmit_xdp_doorbell(struct mlx5e_sq *sq)
640641
mlx5e_tx_notify_hw(sq, &wqe->ctrl, 0);
641642
}
642643

643-
static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
644+
static inline bool mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
644645
struct mlx5e_dma_info *di,
645646
const struct xdp_buff *xdp)
646647
{
@@ -662,7 +663,7 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
662663
MLX5E_SW2HW_MTU(rq->netdev->mtu) < dma_len)) {
663664
rq->stats.xdp_drop++;
664665
mlx5e_page_release(rq, di, true);
665-
return;
666+
return false;
666667
}
667668

668669
if (unlikely(!mlx5e_sq_has_room_for(sq, MLX5E_XDP_TX_WQEBBS))) {
@@ -673,7 +674,7 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
673674
}
674675
rq->stats.xdp_tx_full++;
675676
mlx5e_page_release(rq, di, true);
676-
return;
677+
return false;
677678
}
678679

679680
dma_len -= MLX5E_XDP_MIN_INLINE;
@@ -703,6 +704,7 @@ static inline void mlx5e_xmit_xdp_frame(struct mlx5e_rq *rq,
703704

704705
sq->db.xdp.doorbell = true;
705706
rq->stats.xdp_tx++;
707+
return true;
706708
}
707709

708710
/* returns true if packet was consumed by xdp */
@@ -728,11 +730,13 @@ static inline int mlx5e_xdp_handle(struct mlx5e_rq *rq,
728730
*len = xdp.data_end - xdp.data;
729731
return false;
730732
case XDP_TX:
731-
mlx5e_xmit_xdp_frame(rq, di, &xdp);
733+
if (unlikely(!mlx5e_xmit_xdp_frame(rq, di, &xdp)))
734+
trace_xdp_exception(rq->netdev, prog, act);
732735
return true;
733736
default:
734737
bpf_warn_invalid_xdp_action(act);
735738
case XDP_ABORTED:
739+
trace_xdp_exception(rq->netdev, prog, act);
736740
case XDP_DROP:
737741
rq->stats.xdp_drop++;
738742
mlx5e_page_release(rq, di, true);

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

+10-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
*/
4343

4444
#include <linux/bpf.h>
45+
#include <linux/bpf_trace.h>
4546
#include <linux/module.h>
4647
#include <linux/kernel.h>
4748
#include <linux/init.h>
@@ -1459,7 +1460,7 @@ nfp_net_rx_drop(struct nfp_net_r_vector *r_vec, struct nfp_net_rx_ring *rx_ring,
14591460
dev_kfree_skb_any(skb);
14601461
}
14611462

1462-
static void
1463+
static bool
14631464
nfp_net_tx_xdp_buf(struct nfp_net *nn, struct nfp_net_rx_ring *rx_ring,
14641465
struct nfp_net_tx_ring *tx_ring,
14651466
struct nfp_net_rx_buf *rxbuf, unsigned int pkt_off,
@@ -1473,13 +1474,13 @@ nfp_net_tx_xdp_buf(struct nfp_net *nn, struct nfp_net_rx_ring *rx_ring,
14731474

14741475
if (unlikely(nfp_net_tx_full(tx_ring, 1))) {
14751476
nfp_net_rx_drop(rx_ring->r_vec, rx_ring, rxbuf, NULL);
1476-
return;
1477+
return false;
14771478
}
14781479

14791480
new_frag = nfp_net_napi_alloc_one(nn, DMA_BIDIRECTIONAL, &new_dma_addr);
14801481
if (unlikely(!new_frag)) {
14811482
nfp_net_rx_drop(rx_ring->r_vec, rx_ring, rxbuf, NULL);
1482-
return;
1483+
return false;
14831484
}
14841485
nfp_net_rx_give_one(rx_ring, new_frag, new_dma_addr);
14851486

@@ -1509,6 +1510,7 @@ nfp_net_tx_xdp_buf(struct nfp_net *nn, struct nfp_net_rx_ring *rx_ring,
15091510

15101511
tx_ring->wr_p++;
15111512
tx_ring->wr_ptr_add++;
1513+
return true;
15121514
}
15131515

15141516
static int nfp_net_run_xdp(struct bpf_prog *prog, void *data, unsigned int len)
@@ -1613,12 +1615,15 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
16131615
case XDP_PASS:
16141616
break;
16151617
case XDP_TX:
1616-
nfp_net_tx_xdp_buf(nn, rx_ring, tx_ring, rxbuf,
1617-
pkt_off, pkt_len);
1618+
if (unlikely(!nfp_net_tx_xdp_buf(nn, rx_ring,
1619+
tx_ring, rxbuf,
1620+
pkt_off, pkt_len)))
1621+
trace_xdp_exception(nn->netdev, xdp_prog, act);
16181622
continue;
16191623
default:
16201624
bpf_warn_invalid_xdp_action(act);
16211625
case XDP_ABORTED:
1626+
trace_xdp_exception(nn->netdev, xdp_prog, act);
16221627
case XDP_DROP:
16231628
nfp_net_rx_give_one(rx_ring, rxbuf->frag,
16241629
rxbuf->dma_addr);

drivers/net/ethernet/qlogic/qede/qede_fp.c

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/netdevice.h>
3333
#include <linux/etherdevice.h>
3434
#include <linux/skbuff.h>
35+
#include <linux/bpf_trace.h>
3536
#include <net/udp_tunnel.h>
3637
#include <linux/ip.h>
3738
#include <net/ipv6.h>
@@ -1016,6 +1017,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
10161017
/* We need the replacement buffer before transmit. */
10171018
if (qede_alloc_rx_buffer(rxq, true)) {
10181019
qede_recycle_rx_bd_ring(rxq, 1);
1020+
trace_xdp_exception(edev->ndev, prog, act);
10191021
return false;
10201022
}
10211023

@@ -1026,6 +1028,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
10261028
dma_unmap_page(rxq->dev, bd->mapping,
10271029
PAGE_SIZE, DMA_BIDIRECTIONAL);
10281030
__free_page(bd->data);
1031+
trace_xdp_exception(edev->ndev, prog, act);
10291032
}
10301033

10311034
/* Regardless, we've consumed an Rx BD */
@@ -1035,6 +1038,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
10351038
default:
10361039
bpf_warn_invalid_xdp_action(act);
10371040
case XDP_ABORTED:
1041+
trace_xdp_exception(edev->ndev, prog, act);
10381042
case XDP_DROP:
10391043
qede_recycle_rx_bd_ring(rxq, cqe->bd_num);
10401044
}

drivers/net/virtio_net.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/virtio.h>
2424
#include <linux/virtio_net.h>
2525
#include <linux/bpf.h>
26+
#include <linux/bpf_trace.h>
2627
#include <linux/scatterlist.h>
2728
#include <linux/if_vlan.h>
2829
#include <linux/slab.h>
@@ -330,7 +331,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
330331
return skb;
331332
}
332333

333-
static void virtnet_xdp_xmit(struct virtnet_info *vi,
334+
static bool virtnet_xdp_xmit(struct virtnet_info *vi,
334335
struct receive_queue *rq,
335336
struct send_queue *sq,
336337
struct xdp_buff *xdp,
@@ -382,10 +383,12 @@ static void virtnet_xdp_xmit(struct virtnet_info *vi,
382383
put_page(page);
383384
} else /* small buffer */
384385
kfree_skb(data);
385-
return; // On error abort to avoid unnecessary kick
386+
/* On error abort to avoid unnecessary kick */
387+
return false;
386388
}
387389

388390
virtqueue_kick(sq->vq);
391+
return true;
389392
}
390393

391394
static u32 do_xdp_prog(struct virtnet_info *vi,
@@ -421,11 +424,14 @@ static u32 do_xdp_prog(struct virtnet_info *vi,
421424
vi->xdp_queue_pairs +
422425
smp_processor_id();
423426
xdp.data = buf;
424-
virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp, data);
427+
if (unlikely(!virtnet_xdp_xmit(vi, rq, &vi->sq[qp], &xdp,
428+
data)))
429+
trace_xdp_exception(vi->dev, xdp_prog, act);
425430
return XDP_TX;
426431
default:
427432
bpf_warn_invalid_xdp_action(act);
428433
case XDP_ABORTED:
434+
trace_xdp_exception(vi->dev, xdp_prog, act);
429435
case XDP_DROP:
430436
return XDP_DROP;
431437
}

include/linux/bpf_trace.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __LINUX_BPF_TRACE_H__
2+
#define __LINUX_BPF_TRACE_H__
3+
4+
#include <trace/events/bpf.h>
5+
#include <trace/events/xdp.h>
6+
7+
#endif /* __LINUX_BPF_TRACE_H__ */

0 commit comments

Comments
 (0)