Skip to content

Commit 2539650

Browse files
Toshiaki Makitaborkmann
authored andcommitted
xdp: Helpers for disabling napi_direct of xdp_return_frame
We need some mechanism to disable napi_direct on calling xdp_return_frame_rx_napi() from some context. When veth gets support of XDP_REDIRECT, it will redirects packets which are redirected from other devices. On redirection veth will reuse xdp_mem_info of the redirection source device to make return_frame work. But in this case .ndo_xdp_xmit() called from veth redirection uses xdp_mem_info which is not guarded by NAPI, because the .ndo_xdp_xmit() is not called directly from the rxq which owns the xdp_mem_info. This approach introduces a flag in bpf_redirect_info to indicate that napi_direct should be disabled even when _rx_napi variant is used as well as helper functions to use it. A NAPI handler who wants to use this flag needs to call xdp_set_return_frame_no_direct() before processing packets, and call xdp_clear_return_frame_no_direct() after xdp_do_flush_map() before exiting NAPI. v4: - Use bpf_redirect_info for storing the flag instead of xdp_mem_info to avoid per-frame copy cost. Signed-off-by: Toshiaki Makita <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 0b19cc0 commit 2539650

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

include/linux/filter.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,14 @@ struct bpf_redirect_info {
543543
struct bpf_map *map;
544544
struct bpf_map *map_to_flush;
545545
unsigned long map_owner;
546+
u32 kern_flags;
546547
};
547548

548549
DECLARE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info);
549550

551+
/* flags for bpf_redirect_info kern_flags */
552+
#define BPF_RI_F_RF_NO_DIRECT BIT(0) /* no napi_direct on return_frame */
553+
550554
/* Compute the linear packet data range [data, data_end) which
551555
* will be accessed by various program types (cls_bpf, act_bpf,
552556
* lwt, ...). Subsystems allowing direct data access must (!)
@@ -775,6 +779,27 @@ static inline bool bpf_dump_raw_ok(void)
775779
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
776780
const struct bpf_insn *patch, u32 len);
777781

782+
static inline bool xdp_return_frame_no_direct(void)
783+
{
784+
struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
785+
786+
return ri->kern_flags & BPF_RI_F_RF_NO_DIRECT;
787+
}
788+
789+
static inline void xdp_set_return_frame_no_direct(void)
790+
{
791+
struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
792+
793+
ri->kern_flags |= BPF_RI_F_RF_NO_DIRECT;
794+
}
795+
796+
static inline void xdp_clear_return_frame_no_direct(void)
797+
{
798+
struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);
799+
800+
ri->kern_flags &= ~BPF_RI_F_RF_NO_DIRECT;
801+
}
802+
778803
static inline int xdp_ok_fwd_dev(const struct net_device *fwd,
779804
unsigned int pktlen)
780805
{

net/core/xdp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,12 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
330330
/* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
331331
xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
332332
page = virt_to_head_page(data);
333-
if (xa)
333+
if (xa) {
334+
napi_direct &= !xdp_return_frame_no_direct();
334335
page_pool_put_page(xa->page_pool, page, napi_direct);
335-
else
336+
} else {
336337
put_page(page);
338+
}
337339
rcu_read_unlock();
338340
break;
339341
case MEM_TYPE_PAGE_SHARED:

0 commit comments

Comments
 (0)