Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'ppp-replace-per-cpu-recursion-counter-with-lock-owner-field'

Sebastian Andrzej Siewior says:

====================
ppp: Replace per-CPU recursion counter with lock-owner field

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 https://lore.kernel.org/all/20250710162403.402739-1-bigeasy@linutronix.de/
v1 https://lore.kernel.org/all/20250627105013.Qtv54bEk@linutronix.de/
====================

Link: https://patch.msgid.link/20250715150806.700536-1-bigeasy@linutronix.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

Paolo Abeni a96cee9b e0c7e315

+29 -9
+29 -9
drivers/net/ppp/ppp_generic.c
··· 107 107 #define PF_TO_PPP(pf) PF_TO_X(pf, struct ppp) 108 108 #define PF_TO_CHANNEL(pf) PF_TO_X(pf, struct channel) 109 109 110 + struct ppp_xmit_recursion { 111 + struct task_struct *owner; 112 + local_lock_t bh_lock; 113 + }; 114 + 110 115 /* 111 116 * Data structure describing one ppp unit. 112 117 * A ppp unit corresponds to a ppp network interface device ··· 125 120 int n_channels; /* how many channels are attached 54 */ 126 121 spinlock_t rlock; /* lock for receive side 58 */ 127 122 spinlock_t wlock; /* lock for transmit side 5c */ 128 - int __percpu *xmit_recursion; /* xmit recursion detect */ 123 + struct ppp_xmit_recursion __percpu *xmit_recursion; /* xmit recursion detect */ 129 124 int mru; /* max receive unit 60 */ 130 125 unsigned int flags; /* control bits 64 */ 131 126 unsigned int xstate; /* transmit state bits 68 */ ··· 1254 1249 spin_lock_init(&ppp->rlock); 1255 1250 spin_lock_init(&ppp->wlock); 1256 1251 1257 - ppp->xmit_recursion = alloc_percpu(int); 1252 + ppp->xmit_recursion = alloc_percpu(struct ppp_xmit_recursion); 1258 1253 if (!ppp->xmit_recursion) { 1259 1254 err = -ENOMEM; 1260 1255 goto err1; 1261 1256 } 1262 - for_each_possible_cpu(cpu) 1263 - (*per_cpu_ptr(ppp->xmit_recursion, cpu)) = 0; 1257 + for_each_possible_cpu(cpu) { 1258 + struct ppp_xmit_recursion *xmit_recursion; 1259 + 1260 + xmit_recursion = per_cpu_ptr(ppp->xmit_recursion, cpu); 1261 + xmit_recursion->owner = NULL; 1262 + local_lock_init(&xmit_recursion->bh_lock); 1263 + } 1264 1264 1265 1265 #ifdef CONFIG_PPP_MULTILINK 1266 1266 ppp->minseq = -1; ··· 1670 1660 1671 1661 static void ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb) 1672 1662 { 1663 + struct ppp_xmit_recursion *xmit_recursion; 1664 + 1673 1665 local_bh_disable(); 1674 1666 1675 - if (unlikely(*this_cpu_ptr(ppp->xmit_recursion))) 1667 + xmit_recursion = this_cpu_ptr(ppp->xmit_recursion); 1668 + if (xmit_recursion->owner == current) 1676 1669 goto err; 1670 + local_lock_nested_bh(&ppp->xmit_recursion->bh_lock); 1671 + xmit_recursion->owner = current; 1677 1672 1678 - (*this_cpu_ptr(ppp->xmit_recursion))++; 1679 1673 __ppp_xmit_process(ppp, skb); 1680 - (*this_cpu_ptr(ppp->xmit_recursion))--; 1681 1674 1675 + xmit_recursion->owner = NULL; 1676 + local_unlock_nested_bh(&ppp->xmit_recursion->bh_lock); 1682 1677 local_bh_enable(); 1683 1678 1684 1679 return; ··· 2184 2169 2185 2170 static void ppp_channel_push(struct channel *pch) 2186 2171 { 2172 + struct ppp_xmit_recursion *xmit_recursion; 2173 + 2187 2174 read_lock_bh(&pch->upl); 2188 2175 if (pch->ppp) { 2189 - (*this_cpu_ptr(pch->ppp->xmit_recursion))++; 2176 + xmit_recursion = this_cpu_ptr(pch->ppp->xmit_recursion); 2177 + local_lock_nested_bh(&pch->ppp->xmit_recursion->bh_lock); 2178 + xmit_recursion->owner = current; 2190 2179 __ppp_channel_push(pch); 2191 - (*this_cpu_ptr(pch->ppp->xmit_recursion))--; 2180 + xmit_recursion->owner = NULL; 2181 + local_unlock_nested_bh(&pch->ppp->xmit_recursion->bh_lock); 2192 2182 } else { 2193 2183 __ppp_channel_push(pch); 2194 2184 }