Skip to content

Clean up and document RCU-based object protection for XDP_REDIRECT #1316

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
43c7221
adding ci files
kernel-patches-bot Jun 9, 2021
cbf06ea
rcu: Create an unrcu_pointer() to remove __rcu from a pointer
paulmckrcu Jun 9, 2021
4f00617
bpf: allow RCU-protected lookups to happen from bh context
tohojo Jun 9, 2021
011a7dd
dev: add rcu_read_lock_bh_held() as a valid check when getting a RCU …
tohojo Jun 9, 2021
63d3e2f
xdp: add proper __rcu annotations to redirect map entries
tohojo Jun 9, 2021
9ed1420
ena: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
8961181
bnxt: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
bf0cd58
thunderx: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
8591f1a
freescale: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
6196072
net: intel: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
b34d35d
marvell: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
f895927
mlx4: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
abf7ce2
nfp: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
8889d6d
qede: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
bd7bcdc
sfc: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
f262bec
netsec: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
ff7469f
stmmac: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
8438459
net: ti: remove rcu_read_lock() around XDP program invocation
tohojo Jun 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
sudo: required
language: bash
dist: focal
services:
- docker
git:
depth: 3

env:
global:
- PROJECT_NAME='libbpf'
- AUTHOR_EMAIL="$(git log -1 --pretty=\"%aE\")"
- REPO_ROOT="$TRAVIS_BUILD_DIR"
- CI_ROOT="$REPO_ROOT/travis-ci"
- VMTEST_ROOT="$CI_ROOT/vmtest"

addons:
apt:
packages:
- qemu-kvm
- zstd
- binutils-dev
- elfutils
- libcap-dev
- libelf-dev
- libdw-dev
- python3-docutils

jobs:
include:
- stage: Builds & Tests
name: Kernel LATEST + selftests
language: bash
env: KERNEL=LATEST
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
18 changes: 0 additions & 18 deletions README
Original file line number Diff line number Diff line change
@@ -1,18 +0,0 @@
Linux kernel
============

There are several guides for kernel developers and users. These guides can
be rendered in a number of formats, like HTML and PDF. Please read
Documentation/admin-guide/README.rst first.

In order to build the documentation, use ``make htmldocs`` or
``make pdfdocs``. The formatted documentation can also be read online at:

https://www.kernel.org/doc/html/latest/

There are various text files in the Documentation/ subdirectory,
several of them using the Restructured Text markup notation.

Please read the Documentation/process/changes.rst file, as it contains the
requirements for building and running the kernel, and information about
the problems which may result by upgrading your kernel.
3 changes: 0 additions & 3 deletions drivers/net/ethernet/amazon/ena/ena_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)
u64 *xdp_stat;
int qid;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_bpf_prog);

if (!xdp_prog)
Expand Down Expand Up @@ -443,8 +442,6 @@ static int ena_xdp_execute(struct ena_ring *rx_ring, struct xdp_buff *xdp)

ena_increase_stat(xdp_stat, 1, &rx_ring->syncp);
out:
rcu_read_unlock();

return verdict;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
xdp_prepare_buff(&xdp, *data_ptr - offset, offset, *len, false);
orig_data = xdp.data;

rcu_read_lock();
act = bpf_prog_run_xdp(xdp_prog, &xdp);
rcu_read_unlock();

tx_avail = bnxt_tx_avail(bp, txr);
/* If the tx ring is not full, we must not update the rx producer yet
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/cavium/thunder/nicvf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,9 +555,7 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
xdp_prepare_buff(&xdp, hard_start, data - hard_start, len, false);
orig_data = xdp.data;

rcu_read_lock();
action = bpf_prog_run_xdp(prog, &xdp);
rcu_read_unlock();

len = xdp.data_end - xdp.data;
/* Check if XDP program has changed headers */
Expand Down
8 changes: 1 addition & 7 deletions drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -2558,13 +2558,9 @@ static u32 dpaa_run_xdp(struct dpaa_priv *priv, struct qm_fd *fd, void *vaddr,
u32 xdp_act;
int err;

rcu_read_lock();

xdp_prog = READ_ONCE(priv->xdp_prog);
if (!xdp_prog) {
rcu_read_unlock();
if (!xdp_prog)
return XDP_PASS;
}

xdp_init_buff(&xdp, DPAA_BP_RAW_SIZE - DPAA_TX_PRIV_DATA_SIZE,
&dpaa_fq->xdp_rxq);
Expand Down Expand Up @@ -2638,8 +2634,6 @@ static u32 dpaa_run_xdp(struct dpaa_priv *priv, struct qm_fd *fd, void *vaddr,
break;
}

rcu_read_unlock();

return xdp_act;
}

Expand Down
3 changes: 0 additions & 3 deletions drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,6 @@ static u32 dpaa2_eth_run_xdp(struct dpaa2_eth_priv *priv,
u32 xdp_act = XDP_PASS;
int err, offset;

rcu_read_lock();

xdp_prog = READ_ONCE(ch->xdp.prog);
if (!xdp_prog)
goto out;
Expand Down Expand Up @@ -414,7 +412,6 @@ static u32 dpaa2_eth_run_xdp(struct dpaa2_eth_priv *priv,

ch->xdp.res |= xdp_act;
out:
rcu_read_unlock();
return xdp_act;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2298,7 +2298,6 @@ static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
struct bpf_prog *xdp_prog;
u32 act;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);

if (!xdp_prog)
Expand Down Expand Up @@ -2329,7 +2328,6 @@ static int i40e_run_xdp(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
break;
}
xdp_out:
rcu_read_unlock();
return result;
}

Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/intel/i40e/i40e_xsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
struct bpf_prog *xdp_prog;
u32 act;

rcu_read_lock();
/* NB! xdp_prog will always be !NULL, due to the fact that
* this path is enabled by setting an XDP program.
*/
Expand All @@ -162,9 +161,7 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)

if (likely(act == XDP_REDIRECT)) {
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
result = !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED;
rcu_read_unlock();
return result;
return !err ? I40E_XDP_REDIR : I40E_XDP_CONSUMED;
}

switch (act) {
Expand All @@ -184,7 +181,6 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp)
result = I40E_XDP_CONSUMED;
break;
}
rcu_read_unlock();
return result;
}

Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/intel/ice/ice_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1129,15 +1129,11 @@ int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
xdp.frame_sz = ice_rx_frame_truesize(rx_ring, size);
#endif

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
if (!xdp_prog) {
rcu_read_unlock();
if (!xdp_prog)
goto construct_skb;
}

xdp_res = ice_run_xdp(rx_ring, &xdp, xdp_prog);
rcu_read_unlock();
if (!xdp_res)
goto construct_skb;
if (xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR)) {
Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/intel/ice/ice_xsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)
struct ice_ring *xdp_ring;
u32 act;

rcu_read_lock();
/* ZC patch is enabled only when XDP program is set,
* so here it can not be NULL
*/
Expand All @@ -473,9 +472,7 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)

if (likely(act == XDP_REDIRECT)) {
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
result = !err ? ICE_XDP_REDIR : ICE_XDP_CONSUMED;
rcu_read_unlock();
return result;
return !err ? ICE_XDP_REDIR : ICE_XDP_CONSUMED;
}

switch (act) {
Expand All @@ -496,7 +493,6 @@ ice_run_xdp_zc(struct ice_ring *rx_ring, struct xdp_buff *xdp)
break;
}

rcu_read_unlock();
return result;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8387,7 +8387,6 @@ static struct sk_buff *igb_run_xdp(struct igb_adapter *adapter,
struct bpf_prog *xdp_prog;
u32 act;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);

if (!xdp_prog)
Expand Down Expand Up @@ -8420,7 +8419,6 @@ static struct sk_buff *igb_run_xdp(struct igb_adapter *adapter,
break;
}
xdp_out:
rcu_read_unlock();
return ERR_PTR(-result);
}

Expand Down
7 changes: 2 additions & 5 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2175,18 +2175,15 @@ static struct sk_buff *igc_xdp_run_prog(struct igc_adapter *adapter,
struct bpf_prog *prog;
int res;

rcu_read_lock();

prog = READ_ONCE(adapter->xdp_prog);
if (!prog) {
res = IGC_XDP_PASS;
goto unlock;
goto out;
}

res = __igc_xdp_run_prog(adapter, prog, xdp);

unlock:
rcu_read_unlock();
out:
return ERR_PTR(-res);
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2199,7 +2199,6 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,
struct xdp_frame *xdpf;
u32 act;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);

if (!xdp_prog)
Expand Down Expand Up @@ -2237,7 +2236,6 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,
break;
}
xdp_out:
rcu_read_unlock();
return ERR_PTR(-result);
}

Expand Down
6 changes: 1 addition & 5 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,12 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter,
struct xdp_frame *xdpf;
u32 act;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
act = bpf_prog_run_xdp(xdp_prog, xdp);

if (likely(act == XDP_REDIRECT)) {
err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
result = !err ? IXGBE_XDP_REDIR : IXGBE_XDP_CONSUMED;
rcu_read_unlock();
return result;
return !err ? IXGBE_XDP_REDIR : IXGBE_XDP_CONSUMED;
}

switch (act) {
Expand All @@ -132,7 +129,6 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter,
result = IXGBE_XDP_CONSUMED;
break;
}
rcu_read_unlock();
return result;
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,6 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,
struct bpf_prog *xdp_prog;
u32 act;

rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);

if (!xdp_prog)
Expand All @@ -1079,7 +1078,6 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf_adapter *adapter,
break;
}
xdp_out:
rcu_read_unlock();
return ERR_PTR(-result);
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -2370,7 +2370,6 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
/* Get number of received packets */
rx_todo = mvneta_rxq_busy_desc_num_get(pp, rxq);

rcu_read_lock();
xdp_prog = READ_ONCE(pp->xdp_prog);

/* Fairness NAPI loop */
Expand Down Expand Up @@ -2448,7 +2447,6 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
xdp_buf.data_hard_start = NULL;
sinfo.nr_frags = 0;
}
rcu_read_unlock();

if (xdp_buf.data_hard_start)
mvneta_xdp_put_buff(pp, rxq, &xdp_buf, &sinfo, -1);
Expand Down
4 changes: 0 additions & 4 deletions drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3852,8 +3852,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
int rx_done = 0;
u32 xdp_ret = 0;

rcu_read_lock();

xdp_prog = READ_ONCE(port->xdp_prog);

/* Get number of received packets and clamp the to-do */
Expand Down Expand Up @@ -3988,8 +3986,6 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
mvpp2_bm_pool_put(port, pool, dma_addr, phys_addr);
}

rcu_read_unlock();

if (xdp_ret & MVPP2_XDP_REDIR)
xdp_do_flush_map();

Expand Down
8 changes: 2 additions & 6 deletions drivers/net/ethernet/mellanox/mlx4/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,9 +679,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud

ring = priv->rx_ring[cq_ring];

/* Protect accesses to: ring->xdp_prog, priv->mac_hash list */
rcu_read_lock();
xdp_prog = rcu_dereference(ring->xdp_prog);
xdp_prog = rcu_dereference_bh(ring->xdp_prog);
xdp_init_buff(&xdp, priv->frag_info[0].frag_stride, &ring->xdp_rxq);
doorbell_pending = false;

Expand Down Expand Up @@ -744,7 +742,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
/* Drop the packet, since HW loopback-ed it */
mac_hash = ethh->h_source[MLX4_EN_MAC_HASH_IDX];
bucket = &priv->mac_hash[mac_hash];
hlist_for_each_entry_rcu(entry, bucket, hlist) {
hlist_for_each_entry_rcu_bh(entry, bucket, hlist) {
if (ether_addr_equal_64bits(entry->mac,
ethh->h_source))
goto next;
Expand Down Expand Up @@ -899,8 +897,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
break;
}

rcu_read_unlock();

if (likely(polled)) {
if (doorbell_pending) {
priv->tx_cq[TX_XDP][cq_ring]->xdp_busy = true;
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/ethernet/netronome/nfp/nfp_net_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,6 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
struct xdp_buff xdp;
int idx;

rcu_read_lock();
xdp_prog = READ_ONCE(dp->xdp_prog);
true_bufsz = xdp_prog ? PAGE_SIZE : dp->fl_bufsz;
xdp_init_buff(&xdp, PAGE_SIZE - NFP_NET_RX_BUF_HEADROOM,
Expand Down Expand Up @@ -2036,7 +2035,6 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
if (!nfp_net_xdp_complete(tx_ring))
pkts_polled = budget;
}
rcu_read_unlock();

return pkts_polled;
}
Expand Down
Loading