Make sure qwx(4) always calls refcnt_init() before other refcnt functions.
authorstsp <stsp@openbsd.org>
Tue, 11 Jun 2024 10:06:35 +0000 (10:06 +0000)
committerstsp <stsp@openbsd.org>
Tue, 11 Jun 2024 10:06:35 +0000 (10:06 +0000)
I recently enabled automatic recovery from firmware crashes. if loading
firmware at boot would fail with a firmware error then the init task would
call refcnt_finalize() via qwx_stop() before refcnt_init() was called and
trigger a KASSERT in the refcnt code.

ok patrick@, who also reported the problem to me and tested the fix

sys/dev/ic/qwx.c
sys/dev/pci/if_qwx_pci.c

index 388eb90..ab17d9e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: qwx.c,v 1.62 2024/05/29 07:24:26 stsp Exp $   */
+/*     $OpenBSD: qwx.c,v 1.63 2024/06/11 10:06:35 stsp Exp $   */
 
 /*
  * Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@@ -23150,7 +23150,8 @@ qwx_init_task(void *arg)
        int s = splnet();
        rw_enter_write(&sc->ioctl_rwl);
 
-       qwx_stop(ifp);
+       if (ifp->if_flags & IFF_RUNNING)
+               qwx_stop(ifp);
 
        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == IFF_UP)
                qwx_init(ifp);
index f661822..c42332b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_qwx_pci.c,v 1.19 2024/05/28 09:26:55 stsp Exp $    */
+/*     $OpenBSD: if_qwx_pci.c,v 1.20 2024/06/11 10:06:35 stsp Exp $    */
 
 /*
  * Copyright 2023 Stefan Sperling <stsp@openbsd.org>
@@ -4091,7 +4091,9 @@ qwx_pci_intr(void *arg)
 #else
                printf("%s: fatal firmware error\n",
                   sc->sc_dev.dv_xname);
-               if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags)) {
+               if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags) &&
+                   (sc->sc_ic.ic_if.if_flags & (IFF_UP | IFF_RUNNING)) ==
+                   (IFF_UP | IFF_RUNNING)) {
                        /* Try to reset the device. */
                        set_bit(ATH11K_FLAG_CRASH_FLUSH, sc->sc_flags);
                        task_add(systq, &sc->init_task);