Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp6828048rdb; Fri, 15 Dec 2023 09:17:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IFARZq5gttdSR0TQdTfRU9+ENguivUQas4SH39fuYPtAsufJZW7LJDUnHzzBzalBZMlEhDJ X-Received: by 2002:a92:ca4a:0:b0:35c:e547:d759 with SMTP id q10-20020a92ca4a000000b0035ce547d759mr12742013ilo.12.1702660640181; Fri, 15 Dec 2023 09:17:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1702660640; cv=none; d=google.com; s=arc-20160816; b=xmQOVWeBzNyDzm0JFiYVGoX0BenjF6wyQTyhvL2ClZSSi6X9wsPf4CpOcgmEr3nM0a K6m+IA98rMExVYLvKB9tN0k0r6QAo2H8CFsx7GjfJGyxzX8+kjcrPVlYqJxMPrs4TyhK nKNDEt80PuKjEd5ngG14v0O2Drrquv9SK+gOXrMEv8nHSShgJx+vTm6AZCBuHz5yJqN/ bkXChIT9oJA0zfQLiDsw6Hv15tsjy3mbRn+v9pdbF4LQ1RD1ln2Vr3DpboVftYUrJYS6 TjtGsYtCc2lRcChCzhFKMDTZtgkIE33A/xkA0o1hdkzNu3Uis0rVSyasTclZ045l2q34 wruA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:dkim-signature:dkim-signature:from; bh=gJvqfL6kfGkcyInYfR34Y5EU2FsYBJr4oMNF68chbko=; fh=ZY+6nLviwER2AAlEGfoMWDyWToloc4Va35xZGvP9HaQ=; b=Bs4e0k/LIkiGTFLP3bG4mP1KkPoeMUauBrSbFEAfQGBcJfV5mCKCWPxg5X8w6nYdYR aDIvc6Z6QXokKeBDhzjj2jN7kAUqHqT2gCqO8LcXHm76qhDckYSAF1CV8ezyGKkWCiFx M6CRhxkoGfIADgDweq8jeK8/dQmBn0UKBEMLu6Nx6wrXVe4g3X0Pzsuas5wA9qBchgFW zZQXR/JHhfkinc215wMSPx6+e/37/s3swbPCOmWUvWack/4P2fSY+otTTvSBvRbHJoE9 Ktn5HtaLGgmNNGgU5obS4sWV/wQFpKzUI7fEMTi8EkQ482mrtTvTm6FKJcHo1pFx8nds YYmw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2frKVfBu; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel+bounces-1382-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-1382-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id i13-20020a6551cd000000b005ca186affedsi8285715pgq.372.2023.12.15.09.17.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Dec 2023 09:17:20 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-1382-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=2frKVfBu; dkim=neutral (no key) header.i=@linutronix.de; spf=pass (google.com: domain of linux-kernel+bounces-1382-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-1382-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id C8296285733 for ; Fri, 15 Dec 2023 17:17:19 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 343E76BB52; Fri, 15 Dec 2023 17:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="2frKVfBu"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XDtMmiv9" X-Original-To: linux-kernel@vger.kernel.org Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1AC1261FD1; Fri, 15 Dec 2023 17:10:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de From: Sebastian Andrzej Siewior DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702660241; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gJvqfL6kfGkcyInYfR34Y5EU2FsYBJr4oMNF68chbko=; b=2frKVfBuTxNCn/YOdDqPDYZ2sctcTtOlZNN7VRsSx5KBQpwgvXQwFEfPLw6meL5XGoMXyu odJ2LoMSj808d8L7BQNEdFJ8NhzX5yli372pUzzryRbWBt4dSR30SMD+us3HkuOsZNtGVl 7SRpX7+5b88RAWlQlXDnwKuY/Zj0drS4EEoNxIUi7s2x65k0c4nlfqbXq5mDT7SzgIUWEe NrokjDvzRvF7PWAG18JNo/ICJZZUWcxpaAbRvrHklPDCkiwtsK3iSqWaTibdYV0L28kr2Q xO7eKDxi7kmQetOaekHkCvzw5cICCTFsegmZRKB+5Q8GsqSAUsK/VJpQkBpBSg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702660241; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gJvqfL6kfGkcyInYfR34Y5EU2FsYBJr4oMNF68chbko=; b=XDtMmiv9Gk7YQYNN+15d696JweHCRkGPHH6mhMrQi75BId2aTtnMH7bXiiai8t3OnICdC7 mpD1I/ZZkX+/hzDQ== To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: "David S. Miller" , Boqun Feng , Daniel Borkmann , Eric Dumazet , Frederic Weisbecker , Ingo Molnar , Jakub Kicinski , Paolo Abeni , Peter Zijlstra , Thomas Gleixner , Waiman Long , Will Deacon , Sebastian Andrzej Siewior , Alexei Starovoitov , Jesper Dangaard Brouer , Jesse Brandeburg , John Fastabend , Tony Nguyen , bpf@vger.kernel.org, intel-wired-lan@lists.osuosl.org Subject: [PATCH net-next 20/24] net: intel: Use nested-BH locking for XDP redirect. Date: Fri, 15 Dec 2023 18:07:39 +0100 Message-ID: <20231215171020.687342-21-bigeasy@linutronix.de> In-Reply-To: <20231215171020.687342-1-bigeasy@linutronix.de> References: <20231215171020.687342-1-bigeasy@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable The per-CPU variables used during bpf_prog_run_xdp() invocation and later during xdp_do_redirect() rely on disabled BH for their protection. Without locking in local_bh_disable() on PREEMPT_RT these data structure require explicit locking. This is a follow-up on the previous change which introduced bpf_run_lock.redirect_lock and uses it now within drivers. The simple way is to acquire the lock before bpf_prog_run_xdp() is invoked and hold it until the end of function. This does not always work because some drivers (cpsw, atlantic) invoke xdp_do_flush() in the same context. Acquiring the lock in bpf_prog_run_xdp() and dropping in xdp_do_redirect() (without touching drivers) does not work because not all driver, which use bpf_prog_run_xdp(), do support XDP_REDIRECT (and invoke xdp_do_redirect()). Ideally the minimal locking scope would be bpf_prog_run_xdp() + xdp_do_redirect() and everything else (error recovery, DMA unmapping, free/ alloc of memory, =E2=80=A6) would happen outside of the locked sectio= n. Cc: Alexei Starovoitov Cc: Jesper Dangaard Brouer Cc: Jesse Brandeburg Cc: John Fastabend Cc: Tony Nguyen Cc: bpf@vger.kernel.org (open list:XDP Cc: intel-wired-lan@lists.osuosl.org Signed-off-by: Sebastian Andrzej Siewior --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1 + drivers/net/ethernet/intel/i40e/i40e_xsk.c | 22 +++++++++-------- drivers/net/ethernet/intel/ice/ice_txrx.c | 1 + drivers/net/ethernet/intel/ice/ice_xsk.c | 21 ++++++++-------- drivers/net/ethernet/intel/igb/igb_main.c | 1 + drivers/net/ethernet/intel/igc/igc_main.c | 5 +++- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 1 + drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c | 24 ++++++++++--------- .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 3 ++- 9 files changed, 46 insertions(+), 33 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethe= rnet/intel/i40e/i40e_txrx.c index dd410b15000f7..76e069ae2183a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -2326,6 +2326,7 @@ static int i40e_run_xdp(struct i40e_ring *rx_ring, st= ruct xdp_buff *xdp, struct =20 prefetchw(xdp->data_hard_start); /* xdp_frame write */ =20 + guard(local_lock_nested_bh)(&bpf_run_lock.redirect_lock); act =3D bpf_prog_run_xdp(xdp_prog, xdp); switch (act) { case XDP_PASS: diff --git a/drivers/net/ethernet/intel/i40e/i40e_xsk.c b/drivers/net/ether= net/intel/i40e/i40e_xsk.c index e99fa854d17f1..2b0c0c1f3ddc8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_xsk.c +++ b/drivers/net/ethernet/intel/i40e/i40e_xsk.c @@ -201,17 +201,19 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring,= struct xdp_buff *xdp, struct i40e_ring *xdp_ring; u32 act; =20 - act =3D bpf_prog_run_xdp(xdp_prog, xdp); + scoped_guard(local_lock_nested_bh, &bpf_run_lock.redirect_lock) { + act =3D bpf_prog_run_xdp(xdp_prog, xdp); =20 - if (likely(act =3D=3D XDP_REDIRECT)) { - err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); - if (!err) - return I40E_XDP_REDIR; - if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) - result =3D I40E_XDP_EXIT; - else - result =3D I40E_XDP_CONSUMED; - goto out_failure; + if (likely(act =3D=3D XDP_REDIRECT)) { + err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); + if (!err) + return I40E_XDP_REDIR; + if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) + result =3D I40E_XDP_EXIT; + else + result =3D I40E_XDP_CONSUMED; + goto out_failure; + } } =20 switch (act) { diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethern= et/intel/ice/ice_txrx.c index 9e97ea8630686..5d4cfa3455b37 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -571,6 +571,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buf= f *xdp, if (!xdp_prog) goto exit; =20 + guard(local_lock_nested_bh)(&bpf_run_lock.redirect_lock); act =3D bpf_prog_run_xdp(xdp_prog, xdp); switch (act) { case XDP_PASS: diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/etherne= t/intel/ice/ice_xsk.c index 99954508184f9..02f89c22d19e3 100644 --- a/drivers/net/ethernet/intel/ice/ice_xsk.c +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c @@ -762,17 +762,18 @@ ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xd= p_buff *xdp, int err, result =3D ICE_XDP_PASS; u32 act; =20 + scoped_guard(local_lock_nested_bh, &bpf_run_lock.redirect_lock) { act =3D bpf_prog_run_xdp(xdp_prog, xdp); - - if (likely(act =3D=3D XDP_REDIRECT)) { - err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); - if (!err) - return ICE_XDP_REDIR; - if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) - result =3D ICE_XDP_EXIT; - else - result =3D ICE_XDP_CONSUMED; - goto out_failure; + if (likely(act =3D=3D XDP_REDIRECT)) { + err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); + if (!err) + return ICE_XDP_REDIR; + if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) + result =3D ICE_XDP_EXIT; + else + result =3D ICE_XDP_CONSUMED; + goto out_failure; + } } =20 switch (act) { diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethern= et/intel/igb/igb_main.c index b2295caa2f0ab..e01be809d030e 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -8621,6 +8621,7 @@ static struct sk_buff *igb_run_xdp(struct igb_adapter= *adapter, =20 prefetchw(xdp->data_hard_start); /* xdp_frame write */ =20 + guard(local_lock_nested_bh)(&bpf_run_lock.redirect_lock); act =3D bpf_prog_run_xdp(xdp_prog, xdp); switch (act) { case XDP_PASS: diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethern= et/intel/igc/igc_main.c index e9bb403bbacf9..8321419b3a307 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -2485,7 +2485,10 @@ static int __igc_xdp_run_prog(struct igc_adapter *ad= apter, struct bpf_prog *prog, struct xdp_buff *xdp) { - u32 act =3D bpf_prog_run_xdp(prog, xdp); + u32 act; + + guard(local_lock_nested_bh)(&bpf_run_lock.redirect_lock); + act =3D bpf_prog_run_xdp(prog, xdp); =20 switch (act) { case XDP_PASS: diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/et= hernet/intel/ixgbe/ixgbe_main.c index 94bde2cad0f47..de564e8b83be2 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -2203,6 +2203,7 @@ static struct sk_buff *ixgbe_run_xdp(struct ixgbe_ada= pter *adapter, =20 prefetchw(xdp->data_hard_start); /* xdp_frame write */ =20 + guard(local_lock_nested_bh)(&bpf_run_lock.redirect_lock); act =3D bpf_prog_run_xdp(xdp_prog, xdp); switch (act) { case XDP_PASS: diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/eth= ernet/intel/ixgbe/ixgbe_xsk.c index 59798bc33298f..b988f758aad49 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c @@ -104,18 +104,20 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *ada= pter, struct xdp_frame *xdpf; u32 act; =20 - xdp_prog =3D READ_ONCE(rx_ring->xdp_prog); - act =3D bpf_prog_run_xdp(xdp_prog, xdp); + scoped_guard(local_lock_nested_bh, &bpf_run_lock.redirect_lock) { + xdp_prog =3D READ_ONCE(rx_ring->xdp_prog); + act =3D bpf_prog_run_xdp(xdp_prog, xdp); =20 - if (likely(act =3D=3D XDP_REDIRECT)) { - err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); - if (!err) - return IXGBE_XDP_REDIR; - if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) - result =3D IXGBE_XDP_EXIT; - else - result =3D IXGBE_XDP_CONSUMED; - goto out_failure; + if (likely(act =3D=3D XDP_REDIRECT)) { + err =3D xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog); + if (!err) + return IXGBE_XDP_REDIR; + if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err =3D=3D -ENOBUFS) + result =3D IXGBE_XDP_EXIT; + else + result =3D IXGBE_XDP_CONSUMED; + goto out_failure; + } } =20 switch (act) { diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/ne= t/ethernet/intel/ixgbevf/ixgbevf_main.c index a44e4bd561421..1c58c08aa15ff 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -1059,7 +1059,8 @@ static struct sk_buff *ixgbevf_run_xdp(struct ixgbevf= _adapter *adapter, if (!xdp_prog) goto xdp_out; =20 - act =3D bpf_prog_run_xdp(xdp_prog, xdp); + scoped_guard(local_lock_nested_bh, &bpf_run_lock.redirect_lock) + act =3D bpf_prog_run_xdp(xdp_prog, xdp); switch (act) { case XDP_PASS: break; --=20 2.43.0