netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field
@ 2025-07-15 15:08 Sebastian Andrzej Siewior
  2025-07-15 15:08 ` [PATCH net-next v3 1/1] " Sebastian Andrzej Siewior
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2025-07-15 15:08 UTC (permalink / raw)
  To: netdev, linux-rt-devel, linux-ppp
  Cc: David S. Miller, Andrew Lunn, Clark Williams, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Steven Rostedt,
	Thomas Gleixner, Guillaume Nault, Sebastian Andrzej Siewior

This is another approach to avoid relying on local_bh_disable() for
locking of per-CPU in ppp.

I redid it with the per-CPU lock and local_lock_nested_bh() as discussed
in v1. The xmit_recursion counter has been removed since it served the
same purpose as the owner field. Both were updated and checked.

The xmit_recursion looks like a counter in ppp_channel_push() but at
this point, the counter should always be 0 so it always serves as a
boolean. Therefore I removed it.

I do admit that this looks easier to review.

v2…v3 https://lore.kernel.org/all/20250710162403.402739-1-bigeasy@linutronix.de/
  - rebase on top of net-next
  - replace "ppp channel" with "ppp unit" in the patch description

v1…v2 https://lore.kernel.org/all/20250627105013.Qtv54bEk@linutronix.de/
  - Instead of rewriting the sequence and adding two owner fields to
    the two variables that may recurse it now adds a per-CPU variable
    for locking and keeping mostly the old code flow.  

Sebastian Andrzej Siewior (1):
  ppp: Replace per-CPU recursion counter with lock-owner field

 drivers/net/ppp/ppp_generic.c | 38 ++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

-- 
2.50.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net-next v3 1/1] ppp: Replace per-CPU recursion counter with lock-owner field
  2025-07-15 15:08 [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field Sebastian Andrzej Siewior
@ 2025-07-15 15:08 ` Sebastian Andrzej Siewior
  2025-07-15 17:37 ` [PATCH net-next v3 0/1] " Guillaume Nault
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2025-07-15 15:08 UTC (permalink / raw)
  To: netdev, linux-rt-devel, linux-ppp
  Cc: David S. Miller, Andrew Lunn, Clark Williams, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Steven Rostedt,
	Thomas Gleixner, Guillaume Nault, Sebastian Andrzej Siewior

The per-CPU variable ppp::xmit_recursion is protecting against recursion
due to wrong configuration of the ppp unit. The per-CPU variable
relies on disabled BH for its locking. Without per-CPU locking in
local_bh_disable() on PREEMPT_RT this data structure requires explicit
locking.

The ppp::xmit_recursion is used as a per-CPU boolean. The counter is
checked early in the send routing and the transmit path is only entered
if the counter is zero. Then the counter is incremented to avoid
recursion. It used to detect recursion on channel::downl and
ppp::wlock.

Create a struct ppp_xmit_recursion and move the counter into it.
Add local_lock_t to the struct and use local_lock_nested_bh() for
locking. Due to possible nesting, the lock cannot be acquired
unconditionally but it requires an owner field to identify recursion
before attempting to acquire the lock.

The counter is incremented and checked only after the lock is acquired.
Since it functions as a boolean rather than a count, and its role is now
superseded by the owner field, it can be safely removed.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/net/ppp/ppp_generic.c | 38 ++++++++++++++++++++++++++---------
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 4cf9d1822a83f..8c98cbd4b06de 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -107,6 +107,11 @@ struct ppp_file {
 #define PF_TO_PPP(pf)		PF_TO_X(pf, struct ppp)
 #define PF_TO_CHANNEL(pf)	PF_TO_X(pf, struct channel)
 
+struct ppp_xmit_recursion {
+	struct task_struct *owner;
+	local_lock_t bh_lock;
+};
+
 /*
  * Data structure describing one ppp unit.
  * A ppp unit corresponds to a ppp network interface device
@@ -120,7 +125,7 @@ struct ppp {
 	int		n_channels;	/* how many channels are attached 54 */
 	spinlock_t	rlock;		/* lock for receive side 58 */
 	spinlock_t	wlock;		/* lock for transmit side 5c */
-	int __percpu	*xmit_recursion; /* xmit recursion detect */
+	struct ppp_xmit_recursion __percpu *xmit_recursion; /* xmit recursion detect */
 	int		mru;		/* max receive unit 60 */
 	unsigned int	flags;		/* control bits 64 */
 	unsigned int	xstate;		/* transmit state bits 68 */
@@ -1249,13 +1254,18 @@ static int ppp_dev_configure(struct net *src_net, struct net_device *dev,
 	spin_lock_init(&ppp->rlock);
 	spin_lock_init(&ppp->wlock);
 
-	ppp->xmit_recursion = alloc_percpu(int);
+	ppp->xmit_recursion = alloc_percpu(struct ppp_xmit_recursion);
 	if (!ppp->xmit_recursion) {
 		err = -ENOMEM;
 		goto err1;
 	}
-	for_each_possible_cpu(cpu)
-		(*per_cpu_ptr(ppp->xmit_recursion, cpu)) = 0;
+	for_each_possible_cpu(cpu) {
+		struct ppp_xmit_recursion *xmit_recursion;
+
+		xmit_recursion = per_cpu_ptr(ppp->xmit_recursion, cpu);
+		xmit_recursion->owner = NULL;
+		local_lock_init(&xmit_recursion->bh_lock);
+	}
 
 #ifdef CONFIG_PPP_MULTILINK
 	ppp->minseq = -1;
@@ -1660,15 +1670,20 @@ static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
 
 static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
 {
+	struct ppp_xmit_recursion *xmit_recursion;
+
 	local_bh_disable();
 
-	if (unlikely(*this_cpu_ptr(ppp->xmit_recursion)))
+	xmit_recursion = this_cpu_ptr(ppp->xmit_recursion);
+	if (xmit_recursion->owner == current)
 		goto err;
+	local_lock_nested_bh(&ppp->xmit_recursion->bh_lock);
+	xmit_recursion->owner = current;
 
-	(*this_cpu_ptr(ppp->xmit_recursion))++;
 	__ppp_xmit_process(ppp, skb);
-	(*this_cpu_ptr(ppp->xmit_recursion))--;
 
+	xmit_recursion->owner = NULL;
+	local_unlock_nested_bh(&ppp->xmit_recursion->bh_lock);
 	local_bh_enable();
 
 	return;
@@ -2169,11 +2184,16 @@ static void __ppp_channel_push(struct channel *pch)
 
 static void ppp_channel_push(struct channel *pch)
 {
+	struct ppp_xmit_recursion *xmit_recursion;
+
 	read_lock_bh(&pch->upl);
 	if (pch->ppp) {
-		(*this_cpu_ptr(pch->ppp->xmit_recursion))++;
+		xmit_recursion = this_cpu_ptr(pch->ppp->xmit_recursion);
+		local_lock_nested_bh(&pch->ppp->xmit_recursion->bh_lock);
+		xmit_recursion->owner = current;
 		__ppp_channel_push(pch);
-		(*this_cpu_ptr(pch->ppp->xmit_recursion))--;
+		xmit_recursion->owner = NULL;
+		local_unlock_nested_bh(&pch->ppp->xmit_recursion->bh_lock);
 	} else {
 		__ppp_channel_push(pch);
 	}
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field
  2025-07-15 15:08 [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field Sebastian Andrzej Siewior
  2025-07-15 15:08 ` [PATCH net-next v3 1/1] " Sebastian Andrzej Siewior
@ 2025-07-15 17:37 ` Guillaume Nault
  2025-07-17 13:40 ` Paolo Abeni
  2025-07-17 13:50 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Guillaume Nault @ 2025-07-15 17:37 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: netdev, linux-rt-devel, linux-ppp, David S. Miller, Andrew Lunn,
	Clark Williams, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Steven Rostedt, Thomas Gleixner

On Tue, Jul 15, 2025 at 05:08:05PM +0200, Sebastian Andrzej Siewior wrote:
> This is another approach to avoid relying on local_bh_disable() for
> locking of per-CPU in ppp.
> 
> I redid it with the per-CPU lock and local_lock_nested_bh() as discussed
> in v1. The xmit_recursion counter has been removed since it served the
> same purpose as the owner field. Both were updated and checked.
> 
> The xmit_recursion looks like a counter in ppp_channel_push() but at
> this point, the counter should always be 0 so it always serves as a
> boolean. Therefore I removed it.
> 
> I do admit that this looks easier to review.

Thanks!

Reviewed-by: Guillaume Nault <gnault@redhat.com>


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field
  2025-07-15 15:08 [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field Sebastian Andrzej Siewior
  2025-07-15 15:08 ` [PATCH net-next v3 1/1] " Sebastian Andrzej Siewior
  2025-07-15 17:37 ` [PATCH net-next v3 0/1] " Guillaume Nault
@ 2025-07-17 13:40 ` Paolo Abeni
  2025-07-17 13:50 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Paolo Abeni @ 2025-07-17 13:40 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior, netdev, linux-rt-devel, linux-ppp
  Cc: David S. Miller, Andrew Lunn, Clark Williams, Eric Dumazet,
	Jakub Kicinski, Simon Horman, Steven Rostedt, Thomas Gleixner,
	Guillaume Nault

On 7/15/25 5:08 PM, Sebastian Andrzej Siewior wrote:
> This is another approach to avoid relying on local_bh_disable() for
> locking of per-CPU in ppp.
> 
> I redid it with the per-CPU lock and local_lock_nested_bh() as discussed
> in v1. The xmit_recursion counter has been removed since it served the
> same purpose as the owner field. Both were updated and checked.
> 
> The xmit_recursion looks like a counter in ppp_channel_push() but at
> this point, the counter should always be 0 so it always serves as a
> boolean. Therefore I removed it.
> 
> I do admit that this looks easier to review.

Thanks for reworking the change. I do agree with the above ;)

FTR no need to add a cover letter to a single patch series.

(but, since the matter at hand is IMHO non trivial, in this specific
case I'll preserve the cover letter)

/P


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field
  2025-07-15 15:08 [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2025-07-17 13:40 ` Paolo Abeni
@ 2025-07-17 13:50 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-07-17 13:50 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: netdev, linux-rt-devel, linux-ppp, davem, andrew+netdev,
	clrkwllms, edumazet, kuba, pabeni, horms, rostedt, tglx, gnault

Hello:

This patch was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Tue, 15 Jul 2025 17:08:05 +0200 you wrote:
> This is another approach to avoid relying on local_bh_disable() for
> locking of per-CPU in ppp.
> 
> I redid it with the per-CPU lock and local_lock_nested_bh() as discussed
> in v1. The xmit_recursion counter has been removed since it served the
> same purpose as the owner field. Both were updated and checked.
> 
> [...]

Here is the summary with links:
  - [net-next,v3,1/1] ppp: Replace per-CPU recursion counter with lock-owner field
    https://git.kernel.org/netdev/net-next/c/d4f6460a4bc5

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-07-17 13:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-15 15:08 [PATCH net-next v3 0/1] ppp: Replace per-CPU recursion counter with lock-owner field Sebastian Andrzej Siewior
2025-07-15 15:08 ` [PATCH net-next v3 1/1] " Sebastian Andrzej Siewior
2025-07-15 17:37 ` [PATCH net-next v3 0/1] " Guillaume Nault
2025-07-17 13:40 ` Paolo Abeni
2025-07-17 13:50 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).