Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Fix locking against myself reported by rin@n.o.
details: https://anonhg.NetBSD.org/src/rev/3363f3048e0c
branches: trunk
changeset: 984979:3363f3048e0c
user: knakahara <knakahara%NetBSD.org@localhost>
date: Tue Aug 03 01:08:18 2021 +0000
description:
Fix locking against myself reported by rin@n.o.
In some machine, INTx interrupts occurs for some reason while holding
txq_lock in softint context.
e.g. https://dmesgd.nycbug.org/index.cgi?do=view&id=6139
The panic message is the following.
====================
[ 50.1699480] panic: LOCKDEBUG: Mutex error: mutex_vector_enter,467: locking against myself
[ 50.1800188] cpu0: Begin traceback...
[ 50.1800188] 0xc7a29ac4: netbsd:db_panic+0xc
[ 50.1900018] 0xc7a29adc: netbsd:vpanic+0x120
[ 50.1999533] 0xc7a29af4: netbsd:aprint_debug
[ 50.1999533] 0xc7a29b34: netbsd:lockdebug_abort1+0x18c
[ 50.2099719] 0xc7a29b74: netbsd:lockdebug_wantlock+0x1e8
[ 50.2199525] 0xc7a29bb4: netbsd:mutex_enter+0x288
[ 50.2299642] 0xc7a29be4: netbsd:wm_intr_legacy+0x9c
[ 50.2299642] 0xc7a29c2c: netbsd:i80321_intr_dispatch+0x138
[ 50.2399631] 0xc7a29de4: netbsd:irq_entry+0x98
[ 50.2499452] 0xc7a29e24: netbsd:entropy_enter+0x88
[ 50.2599996] 0xc7a29e6c: netbsd:rnd_add_data_1+0x50
[ 50.2699565] 0xc7a29ebc: netbsd:rnd_add_data+0x10c
[ 50.2699565] 0xc7a29ed4: netbsd:rnd_add_uint32+0x28
[ 50.2799524] 0xc7a29f1c: netbsd:wm_txeof+0x2c0
[ 50.2899527] 0xc7a29f5c: netbsd:wm_handle_queue+0x44
[ 50.3000257] 0xc7a29fac: netbsd:softint_thread+0x130
[ 50.3100119] cpu0: End traceback...
====================
To fix this panic, stop wm(4) interrupts before calling softint.
This behavior is similar to MSI-X polling mode.
Reviewed by msaitoh@n.o, tested by rin@n.o, thanks.
diffstat:
sys/dev/pci/if_wm.c | 34 +++++++++++++++++++++++++++++-----
1 files changed, 29 insertions(+), 5 deletions(-)
diffs (98 lines):
diff -r a32e65526d2a -r 3363f3048e0c sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Mon Aug 02 23:49:26 2021 +0000
+++ b/sys/dev/pci/if_wm.c Tue Aug 03 01:08:18 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.705 2021/06/16 00:21:18 riastradh Exp $ */
+/* $NetBSD: if_wm.c,v 1.706 2021/08/03 01:08:18 knakahara Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -82,7 +82,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.705 2021/06/16 00:21:18 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.706 2021/08/03 01:08:18 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -9774,6 +9774,20 @@
softint_schedule(wmq->wmq_si);
}
+static inline void
+wm_legacy_intr_disable(struct wm_softc *sc)
+{
+
+ CSR_WRITE(sc, WMREG_IMC, 0xffffffffU);
+}
+
+static inline void
+wm_legacy_intr_enable(struct wm_softc *sc)
+{
+
+ CSR_WRITE(sc, WMREG_IMS, sc->sc_icr);
+}
+
/*
* wm_intr_legacy:
*
@@ -9788,6 +9802,7 @@
struct wm_rxqueue *rxq = &wmq->wmq_rxq;
uint32_t icr, rndval = 0;
int handled = 0;
+ bool more = false;
while (1 /* CONSTCOND */) {
icr = CSR_READ(sc, WMREG_ICR);
@@ -9822,7 +9837,7 @@
* as if_percpuq_enqueue() just call softint_schedule().
* So, we can call wm_rxeof() in interrupt context.
*/
- wm_rxeof(rxq, UINT_MAX);
+ more = wm_rxeof(rxq, UINT_MAX);
mutex_exit(rxq->rxq_lock);
mutex_enter(txq->txq_lock);
@@ -9840,7 +9855,7 @@
WM_Q_EVCNT_INCR(txq, txdw);
}
#endif
- wm_txeof(txq, UINT_MAX);
+ more |= wm_txeof(txq, UINT_MAX);
mutex_exit(txq->txq_lock);
WM_CORE_LOCK(sc);
@@ -9869,8 +9884,9 @@
rnd_add_uint32(&sc->rnd_source, rndval);
- if (handled) {
+ if (more) {
/* Try to get more packets going. */
+ wm_legacy_intr_disable(sc);
wmq->wmq_txrx_use_workqueue = sc->sc_txrx_use_workqueue;
wm_sched_handle_queue(sc, wmq);
}
@@ -9883,6 +9899,10 @@
{
struct wm_softc *sc = wmq->wmq_txq.txq_sc;
+ if (__predict_false(!wm_is_using_msix(sc))) {
+ return wm_legacy_intr_disable(sc);
+ }
+
if (sc->sc_type == WM_T_82574)
CSR_WRITE(sc, WMREG_IMC,
ICR_TXQ(wmq->wmq_id) | ICR_RXQ(wmq->wmq_id));
@@ -9900,6 +9920,10 @@
wm_itrs_calculate(sc, wmq);
+ if (__predict_false(!wm_is_using_msix(sc))) {
+ return wm_legacy_intr_enable(sc);
+ }
+
/*
* ICR_OTHER which is disabled in wm_linkintr_msix() is enabled here.
* There is no need to care about which of RXQ(0) and RXQ(1) enable
Home |
Main Index |
Thread Index |
Old Index