* [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context
@ 2026-09-30 18:54 Karl Mehltretter
2026-10-01 7:57 ` Sebastian Andrzej Siewior
2026-10-04 12:29 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Arend van Spriel
0 siblings, 2 replies; 6+ messages in thread
From: Karl Mehltretter @ 2026-09-30 18:54 UTC (permalink / raw)
To: linux-wireless
Cc: Karl Mehltretter, Arend van Spriel, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, David S. Miller, Eric Dumazet,
brcm80211, brcm80211-dev-list.pdl, linux-kernel, linux-rt-devel,
stable
With the default fcmode=0, netpoll calls ndo_start_xmit() with hard
interrupts disabled and reaches brcmf_sdio_bus_txdata() directly. The
function takes txq_lock with spin_lock_bh(), and the queue helper takes
the embedded sk_buff_head lock. These locks may sleep on PREEMPT_RT.
On non-RT, spin_unlock_bh() can run pending networking softirqs before
netpoll releases the transmit lock, causing a recursive transmit
deadlock.
Use spin_trylock() for IRQ-disabled calls and enqueue with the unlocked
skb helper while holding txq_lock. On PREEMPT_RT, reject hard IRQ and NMI
callers, where rt-spinlocks cannot be acquired. If the lock is busy or
the queue is full, return through the existing drop path. Do not evict an
older packet from this context. Suppress the queue-full printk because
netconsole can recursively enter this path.
The flow-control callback takes another spinlock, so defer it when an
IRQ-disabled enqueue reaches TXHI. The data worker rechecks the bus state
and queue length under txq_lock before stopping the queue. Existing TXLOW
handling wakes the queue after it drains.
This fixes the direct SDIO transmit path used by fcmode=0. Modes 1 and 2
take the FWS lock first and need a separate change.
Fixes: ac3d9dd034e5 ("netpoll: make ndo_poll_controller() optional")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
Testing:
- This revision passed W=1 sdio.o builds on x86_64 PREEMPT_RT and
x86_64 PREEMPT kernels.
- This exact revision, together with the netpoll v2 fixes, passed 10/10
counted physical boots across a Pi 400 and Pi 500+: three RT and two
non-RT boots per board. The softirq trigger delivered 64/64 records on
every boot with no driver drop. Every lock-contention run freed all 64
skbs without timeout, and every TXHI queue stop subsequently woke.
- Each board and kernel flavor completed a 1,800-second numbered stream,
ten repeated TXHI cycles and a Wi-Fi reconnect. No counted boot
reported an atomic-sleep warning, new lockdep splat, stall or lockup.
- The exact revision passed combined RT and non-RT QEMU softirq,
lock-contention and TXHI stop/drain/wake tests.
- An unpatched PREEMPT_RT Pi 400 reproduced the atomic-sleep report. An
unpatched non-RT Pi 400 deadlocked and produced 32 RCU stall reports.
- An unpatched PREEMPT_RT Pi 500+ reproduced 21 atomic-sleep reports.
- All brcmfmac tests used the default fcmode=0.
.../broadcom/brcm80211/brcmfmac/sdio.c | 91 +++++++++++++++++--
1 file changed, 85 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 381801af3a..170450306d 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -516,6 +516,7 @@ struct brcmf_sdio {
bool dpc_running;
bool txoff; /* Transmit flow-controlled */
+ bool txoff_pending; /* Deferred transmit flow control */
struct brcmf_sdio_count sdcnt;
bool sr_enabled; /* SaveRestore enabled */
bool sleeping;
@@ -2796,8 +2797,53 @@ static bool brcmf_sdio_prec_enq(struct pktq *q, struct sk_buff *pkt, int prec)
return p != NULL;
}
+/*
+ * The caller holds txq_lock with hard IRQs disabled. Avoid the skb queue
+ * lock, which may sleep on PREEMPT_RT.
+ */
+static bool brcmf_sdio_prec_enq_irqoff(struct pktq *q, struct sk_buff *pkt,
+ int prec)
+{
+ struct sk_buff_head *list = &q->q[prec].skblist;
+
+ if (pktq_pfull(q, prec) || pktq_full(q))
+ return false;
+
+ __skb_queue_tail(list, pkt);
+ q->len++;
+ if (q->hi_prec < prec)
+ q->hi_prec = prec;
+
+ return true;
+}
+
+static bool brcmf_sdio_txq_lock(struct brcmf_sdio *bus, bool irq_off)
+ __cond_acquires(true, &bus->txq_lock)
+{
+ if (irq_off) {
+ if (IS_ENABLED(CONFIG_PREEMPT_RT) &&
+ (in_hardirq() || in_nmi()))
+ return false;
+ return spin_trylock(&bus->txq_lock);
+ }
+
+ spin_lock_bh(&bus->txq_lock);
+ return true;
+}
+
+static void brcmf_sdio_txq_unlock(struct brcmf_sdio *bus, bool irq_off)
+ __releases(&bus->txq_lock)
+{
+ if (irq_off)
+ spin_unlock(&bus->txq_lock);
+ else
+ spin_unlock_bh(&bus->txq_lock);
+}
+
static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
{
+ bool irq_off = irqs_disabled();
+ bool enqueued;
int ret = -EBADE;
uint prec;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -2826,22 +2872,39 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
bus->sdcnt.fcqueued++;
/* Priority based enq */
- spin_lock_bh(&bus->txq_lock);
+ if (!brcmf_sdio_txq_lock(bus, irq_off)) {
+ skb_pull(pkt, bus->tx_hdrlen);
+ return -EBUSY;
+ }
+
/* reset bus_flags in packet cb */
*(u16 *)(pkt->cb) = 0;
- if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec)) {
+ if (irq_off)
+ enqueued = brcmf_sdio_prec_enq_irqoff(&bus->txq, pkt, prec);
+ else
+ enqueued = brcmf_sdio_prec_enq(&bus->txq, pkt, prec);
+
+ if (!enqueued) {
skb_pull(pkt, bus->tx_hdrlen);
- brcmf_err("out of bus->txq !!!\n");
+ /* Avoid netconsole recursion. */
+ if (!irq_off)
+ brcmf_err("out of bus->txq !!!\n");
ret = -ENOSR;
} else {
ret = 0;
}
if (pktq_len(&bus->txq) >= TXHI) {
- bus->txoff = true;
- brcmf_proto_bcdc_txflowblock(dev, true);
+ if (irq_off) {
+ WRITE_ONCE(bus->txoff_pending, true);
+ } else {
+ WRITE_ONCE(bus->txoff_pending, false);
+ bus->txoff = true;
+ brcmf_proto_bcdc_txflowblock(dev, true);
+ }
}
- spin_unlock_bh(&bus->txq_lock);
+
+ brcmf_sdio_txq_unlock(bus, irq_off);
#ifdef DEBUG
if (pktq_plen(&bus->txq, prec) > qcount[prec])
@@ -3754,6 +3817,21 @@ static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
}
}
+static void brcmf_sdio_deferred_txflowblock(struct brcmf_sdio *bus)
+{
+ if (!READ_ONCE(bus->txoff_pending))
+ return;
+
+ spin_lock_bh(&bus->txq_lock);
+ WRITE_ONCE(bus->txoff_pending, false);
+ if (bus->sdiodev->state == BRCMF_SDIOD_DATA && !bus->txoff &&
+ pktq_len(&bus->txq) >= TXHI) {
+ bus->txoff = true;
+ brcmf_proto_bcdc_txflowblock(bus->sdiodev->dev, true);
+ }
+ spin_unlock_bh(&bus->txq_lock);
+}
+
static void brcmf_sdio_dataworker(struct work_struct *work)
{
struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
@@ -3763,6 +3841,7 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
wmb();
while (READ_ONCE(bus->dpc_triggered)) {
bus->dpc_triggered = false;
+ brcmf_sdio_deferred_txflowblock(bus);
brcmf_sdio_dpc(bus);
bus->idlecount = 0;
}
base-commit: 6f63e919fe1e335b8abcb3a28bfd4804a98d875a
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context
2026-09-30 18:54 [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Karl Mehltretter
@ 2026-10-01 7:57 ` Sebastian Andrzej Siewior
2026-10-01 23:41 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll contextg Karl Mehltretter
2026-10-04 12:29 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Arend van Spriel
1 sibling, 1 reply; 6+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-10-01 7:57 UTC (permalink / raw)
To: Karl Mehltretter
Cc: linux-wireless, Arend van Spriel, Clark Williams, Steven Rostedt,
David S. Miller, Eric Dumazet, brcm80211, brcm80211-dev-list.pdl,
linux-kernel, linux-rt-devel, stable
On 2026-09-30 20:54:17 [+0200], Karl Mehltretter wrote:
> With the default fcmode=0, netpoll calls ndo_start_xmit() with hard
> interrupts disabled and reaches brcmf_sdio_bus_txdata() directly. The
> function takes txq_lock with spin_lock_bh(), and the queue helper takes
> the embedded sk_buff_head lock. These locks may sleep on PREEMPT_RT.
> On non-RT, spin_unlock_bh() can run pending networking softirqs before
> netpoll releases the transmit lock, causing a recursive transmit
> deadlock.
>
> Use spin_trylock() for IRQ-disabled calls and enqueue with the unlocked
> skb helper while holding txq_lock. On PREEMPT_RT, reject hard IRQ and NMI
> callers, where rt-spinlocks cannot be acquired. If the lock is busy or
> the queue is full, return through the existing drop path. Do not evict an
> older packet from this context. Suppress the queue-full printk because
> netconsole can recursively enter this path.
>
> The flow-control callback takes another spinlock, so defer it when an
> IRQ-disabled enqueue reaches TXHI. The data worker rechecks the bus state
> and queue length under txq_lock before stopping the queue. Existing TXLOW
> handling wakes the queue after it drains.
>
> This fixes the direct SDIO transmit path used by fcmode=0. Modes 1 and 2
> take the FWS lock first and need a separate change.
Is this the only affected driver?
Do you have maybe a backtrace?
> Fixes: ac3d9dd034e5 ("netpoll: make ndo_poll_controller() optional")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Sebastian
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll contextg
2026-10-01 7:57 ` Sebastian Andrzej Siewior
@ 2026-10-01 23:41 ` Karl Mehltretter
0 siblings, 0 replies; 6+ messages in thread
From: Karl Mehltretter @ 2026-10-01 23:41 UTC (permalink / raw)
To: Sebastian Andrzej Siewior, g
Cc: linux-wireless, Arend van Spriel, Clark Williams, Steven Rostedt,
David S. Miller, Eric Dumazet, brcm80211, brcm80211-dev-list.pdl,
linux-kernel, linux-rt-devel, stable
On Thu, Oct 01, 2026 at 09:57:55AM +0100, Sebastian Andrzej Siewior wrote:
> On 2026-09-30 20:54:17 [+0200], Karl Mehltretter wrote:
> > This fixes the direct SDIO transmit path used by fcmode=0. Modes 1 and 2
> > take the FWS lock first and need a separate change.
>
> Is this the only affected driver?
I also reproduced a sleeping-lock warning with 8139cp on PREEMPT_RT
using QEMU's RTL8139C+ device. Enabling a dynamic netconsole target caused
the printer thread to enter cp_start_xmit() with hard interrupts disabled:
BUG: sleeping function called from invalid context
in_atomic(): 0, irqs_disabled(): 1, pid: 107, name: pr/netcon0
hardirqs last disabled at netpoll_send_skb+0x1c8/0x3d0
rt_spin_lock
cp_start_xmit+0x31/0x8b6 [8139cp]
netpoll_start_xmit+0x18e/0x260
netpoll_send_skb+0x37a/0x3d0
netconsole_write+0x56d/0x820
That was one reproduction on the netdev base a7bfaba4823e. I have not
established how many drivers are affected.
Source inspection also identified 8139too and macb as candidates: their
transmit paths take ordinary spinlock_t locks. I have not reproduced the
warning with either driver.
The earlier netpoll/NBCON discussion concerns NAPI polling and
scheduler-lock deadlocks, rather than this driver-lock warning:
https://lore.kernel.org/linux-rt-devel/20260618111554.2n0pP_O9@linutronix.de/
> Do you have maybe a backtrace?
>
This is the original Pi 400 report on 7.3-rc3 with PREEMPT_RT. That kernel
also had unrelated allocation-test patches applied. DEBUG_ATOMIC_SLEEP
was disabled, so this report is the BH-disable warning:
DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt))
WARNING: kernel/softirq.c:199 at __local_bh_disable_ip+0xd8/0x200
CPU#0: pr/netcon0/769
Call trace:
__local_bh_disable_ip+0xd8/0x200
brcmf_sdio_bus_txdata+0x90/0x2b0 [brcmfmac]
brcmf_proto_bcdc_txdata+0x90/0xb0 [brcmfmac]
brcmf_proto_bcdc_tx_queue_data+0x60/0xa0 [brcmfmac]
brcmf_netdev_start_xmit+0x164/0x390 [brcmfmac]
netpoll_start_xmit+0x160/0x218
netpoll_send_skb+0x208/0x2b0
netpoll_send_udp+0x298/0x478
netconsole_write+0x440/0x7a0
netconsole_write_basic+0x20/0x40
nbcon_emit_next_record+0x208/0x2a8
nbcon_emit_one+0xc8/0x110
nbcon_kthread_func+0x184/0x210
Thanks,
Karl
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context
2026-09-30 18:54 [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Karl Mehltretter
2026-10-01 7:57 ` Sebastian Andrzej Siewior
@ 2026-10-04 12:29 ` Arend van Spriel
2026-10-06 4:18 ` Karl Mehltretter
1 sibling, 1 reply; 6+ messages in thread
From: Arend van Spriel @ 2026-10-04 12:29 UTC (permalink / raw)
To: Karl Mehltretter
Cc: Arend van Spriel, linux-wireless, Sebastian Andrzej Siewior,
Clark Williams, Steven Rostedt, David S . Miller, Eric Dumazet,
brcm80211, brcm80211-dev-list.pdl, linux-kernel, linux-rt-devel,
stable
On Wed, 30 Sep 2026 20:54:17 +0200, Karl Mehltretter wrote:
> With the default fcmode=0, netpoll calls ndo_start_xmit() with hard
> interrupts disabled and reaches brcmf_sdio_bus_txdata() directly. The
> function takes txq_lock with spin_lock_bh(), and the queue helper takes
> the embedded sk_buff_head lock. These locks may sleep on PREEMPT_RT.
> On non-RT, spin_unlock_bh() can run pending networking softirqs before
> netpoll releases the transmit lock, causing a recursive transmit
> deadlock.
>
> Use spin_trylock() for IRQ-disabled calls and enqueue with the unlocked
> skb helper while holding txq_lock. On PREEMPT_RT, reject hard IRQ and NMI
> callers, where rt-spinlocks cannot be acquired. If the lock is busy or
> the queue is full, return through the existing drop path. Do not evict an
> older packet from this context. Suppress the queue-full printk because
> netconsole can recursively enter this path.
>
> The flow-control callback takes another spinlock, so defer it when an
> IRQ-disabled enqueue reaches TXHI. The data worker rechecks the bus state
> and queue length under txq_lock before stopping the queue. Existing TXLOW
> handling wakes the queue after it drains.
>
> This fixes the direct SDIO transmit path used by fcmode=0. Modes 1 and 2
> take the FWS lock first and need a separate change.
>
> Fixes: ac3d9dd034e5 ("netpoll: make ndo_poll_controller() optional")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
[...]
> @@ -2796,8 +2797,53 @@ static bool brcmf_sdio_prec_enq(struct pktq *q, struct sk_buff *pkt, int prec)
> return p != NULL;
> }
>
> +/*
> + * The caller holds txq_lock with hard IRQs disabled. Avoid the skb queue
> + * lock, which may sleep on PREEMPT_RT.
> + */
> +static bool brcmf_sdio_prec_enq_irqoff(struct pktq *q, struct sk_buff *pkt,
> + int prec)
> +{
> + struct sk_buff_head *list = &q->q[prec].skblist;
> +
> + if (pktq_pfull(q, prec) || pktq_full(q))
> + return false;
> +
> + __skb_queue_tail(list, pkt);
> + q->len++;
> + if (q->hi_prec < prec)
> + q->hi_prec = prec;
> +
> + return true;
> +}
Looking at brcmf_sdio_prec_enq(), it performs essentially the same check on
its fast path (!pktq_pfull(q, prec) && !pktq_full(q)) before calling
brcmu_pktq_penq(), and only falls back to packet eviction when the queue is
full.
Since bus->txq_lock is always held by the caller, using the unlocked
__skb_queue_tail() is safe in both contexts (the embedded skblist spinlock
in brcmu_pktq_penq() has always been redundant in sdio.c).
Is there an opportunity to reuse/refactor brcmf_sdio_prec_enq() rather than
adding a separate brcmf_sdio_prec_enq_irqoff() helper? For example, passing
a can_evict parameter:
static bool brcmf_sdio_prec_enq(struct pktq *q, struct sk_buff *pkt, int prec,
bool can_evict)
{
struct sk_buff_head *list = &q->q[prec].skblist;
struct sk_buff *p;
int eprec = -1;
/* Fast case, precedence queue is not full and we are also not
* exceeding total queue length
*/
if (!pktq_pfull(q, prec) && !pktq_full(q))
goto enq;
if (!can_evict)
return false;
/* Determine precedence from which to evict packet, if any */
if (pktq_pfull(q, prec)) {
eprec = prec;
} else if (pktq_full(q)) {
p = brcmu_pktq_peek_tail(q, &eprec);
if (eprec > prec)
return false;
}
/* Evict if needed */
if (eprec >= 0) {
/* Detect queueing to unconfigured precedence */
if (eprec == prec)
return false; /* refuse newer (incoming) packet */
/* Evict packet according to discard policy */
p = brcmu_pktq_pdeq_tail(q, eprec);
if (p == NULL)
brcmf_err("brcmu_pktq_pdeq_tail() failed\n");
brcmu_pkt_buf_free_skb(p);
}
enq:
__skb_queue_tail(list, pkt);
q->len++;
if (q->hi_prec < prec)
q->hi_prec = prec;
return true;
}
Then in brcmf_sdio_bus_txdata():
if (!brcmf_sdio_prec_enq(&bus->txq, pkt, prec, !irq_off)) {
skb_pull(pkt, bus->tx_hdrlen);
if (!irq_off)
brcmf_err("out of bus->txq !!!\n");
ret = -ENOSR;
} else {
ret = 0;
}
That keeps the queuing logic in one place, eliminates the duplicate helper,
and simplifies the caller.
Regards,
Arend
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context
2026-10-04 12:29 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Arend van Spriel
@ 2026-10-06 4:18 ` Karl Mehltretter
2026-10-06 8:27 ` Arend van Spriel
0 siblings, 1 reply; 6+ messages in thread
From: Karl Mehltretter @ 2026-10-06 4:18 UTC (permalink / raw)
To: Arend van Spriel
Cc: linux-wireless, Sebastian Andrzej Siewior, Clark Williams,
Steven Rostedt, David S . Miller, Eric Dumazet, brcm80211,
brcm80211-dev-list.pdl, linux-kernel, linux-rt-devel, stable
On Sun, Oct 04, 2026 at 05:29:10AM +0100, Arend van Spriel wrote:
> Is there an opportunity to reuse/refactor brcmf_sdio_prec_enq() rather than
> adding a separate brcmf_sdio_prec_enq_irqoff() helper? For example, passing
> a can_evict parameter:
>
Thanks for the review!
Sharing the helper with a can_evict argument is cleaner.
One queue user does not hold txq_lock: brcmf_fws_bus_txq_cleanup()
dequeues through brcmu_pktq_pdeq_match().
Lockdep instrumentation in fcmode=1 and 2 confirmed that cleanup enters
without txq_lock.
I combined the helpers, but kept brcmu_pktq_penq() for normal calls.
Karl
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context
2026-10-06 4:18 ` Karl Mehltretter
@ 2026-10-06 8:27 ` Arend van Spriel
0 siblings, 0 replies; 6+ messages in thread
From: Arend van Spriel @ 2026-10-06 8:27 UTC (permalink / raw)
To: Karl Mehltretter
Cc: linux-wireless, Sebastian Andrzej Siewior, Clark Williams,
Steven Rostedt, David S . Miller, Eric Dumazet, brcm80211,
brcm80211-dev-list.pdl, linux-kernel, linux-rt-devel, stable
On 06/10/2026 06:18, Karl Mehltretter wrote:
> On Sun, Oct 04, 2026 at 05:29:10AM +0100, Arend van Spriel wrote:
>> Is there an opportunity to reuse/refactor brcmf_sdio_prec_enq() rather than
>> adding a separate brcmf_sdio_prec_enq_irqoff() helper? For example, passing
>> a can_evict parameter:
>>
>
> Thanks for the review!
>
> Sharing the helper with a can_evict argument is cleaner.
>
> One queue user does not hold txq_lock: brcmf_fws_bus_txq_cleanup()
> dequeues through brcmu_pktq_pdeq_match().
>
> Lockdep instrumentation in fcmode=1 and 2 confirmed that cleanup enters
> without txq_lock.
This is an observation unrelated to the patch, right? You mentioned in
the patch it only covers fcmode=0, right?
> I combined the helpers, but kept brcmu_pktq_penq() for normal calls.
Sure.
Regards,
Arend
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-06 8:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 18:54 [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Karl Mehltretter
2026-10-01 7:57 ` Sebastian Andrzej Siewior
2026-10-01 23:41 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll contextg Karl Mehltretter
2026-10-04 12:29 ` [PATCH] wifi: brcmfmac: avoid sleeping tx locks in netpoll context Arend van Spriel
2026-10-06 4:18 ` Karl Mehltretter
2026-10-06 8:27 ` Arend van Spriel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®