On Tue, May 19, 2020 at 09:52:57AM -0700, Jonathon Fletcher wrote:
> 
> 
> >Synopsis:    ure RTL8153 panics on 6.7 - was stable on 6.6
> 
> >Category:    <PR category (one line)>
> 
> >Environment:
>       System      : OpenBSD 6.7
>       Details     : OpenBSD 6.7 (GENERIC.MP) #1: Sat May 16 16:33:02 MDT 2020
>                        
> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
> 
>       Architecture: OpenBSD.amd64
>       Machine     : amd64
> 
> >Description:
> ** PRELIMINARY BUG REPORT - INCOMPLETE INFO **
> 
> 
> USB ure with RTL8153 on 6.7 panics. Same hardware stable on 6.6.
> 
> ure0 at uhub0 port 14 configuration 1 interface 0 "Realtek USB 10/100/1000 
> LAN" rev 3.00/30.00 addr 5
> ure0: RTL8153 (0x5c30), address a0:ce:c8:cd:ba:d1
> rgephy0 at ure0 phy 0: RTL8251 PHY, rev. 0
> 
> 
> Under load (estimated 50MB/s for approximate 5 minutes), kernel panics:
> 
> panic: assertwaitok: non-zero mutex count: 1
> Stopped at db_enter+0xl0: popq %rbp
>     TID PID UID PRFLAGS PFLAGS CPU COMMAND
> db_enter() at db_enter+0x10
> panic(ffffffff81c8al98) at panic+0x128
> assertwaitok() at assertwaitok+0xc7
> mi_switch at mi_switch+0x40
> sleep_finish(ffff800022e816b8,1) at sleep_finish+0x84
> sleep_finish_all(ffff800022e816b8,1) at sleep_finish_all+0x21
> tsleepCfffffd84465a24b0,10,ffffffff81c9c412,0) at tsleep+0xd6
> usbd_transfer(fffffd84465a24b0) at usbd_transfer+0x204
> usbd_do_request_flagsCffff80000052e600,ffff800022e81810,ffff800022e8180c,0,0,1388)
>  at usbd_do_request_fLags+0x139
> ure_reset(ffff800000538000) at ure_reset+0x5e
> ure_stop(ffff800000538000) at ure_stop+0x21
> ure_encap(ffff800000538000, fffffd809e390f00) at ure_encap+0xf2
> ure_start(ffff8000005380d0) at ure_start+0x8b
> if_qstart_compat(ffff800000538348) at if_qstart_conpat+0x2e
> end trace frame: 0xffff800022e819b0, count: 0
> https://www.openbsd.org/ddb.htnl describes the minimum info required in bug 
> reports. Insufficient info makes it difficult to find and fix bugs.
> ddb{0}> 
> 
> 
> Above panic OCR’d from a picture and may have errors. I hope to provide more 
> info / trace later.
> 
> 
> Aside:
> 
> Same panic occurred with RTL8156 - first 6.7 panic. After that I reverted to 
> the RTL8153 above in case panic was limited to the newly-supported hardware.
> 
> ure0 at uhub0 port 14 configuration 1 interface 0 "Realtek USB 10/100/1G/2.5G 
> LAN" rev 3.20/30.00 addr 5
> ure0: RTL8156 (0x7030), address 00:e0:4c:ab:64:5a

Thanks for the report.  Could you test this diff?  Thanks.

Index: sys/dev/usb/if_ure.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_ure.c,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 if_ure.c
--- sys/dev/usb/if_ure.c        10 Mar 2020 01:11:30 -0000      1.14
+++ sys/dev/usb/if_ure.c        21 May 2020 07:03:53 -0000
@@ -117,7 +117,7 @@ void                ure_miibus_writereg(struct device 
 void           ure_lock_mii(struct ure_softc *);
 void           ure_unlock_mii(struct ure_softc *);
 
-int            ure_encap(struct ure_softc *, struct mbuf *);
+int            ure_encap(struct ure_softc *, struct mbuf *, int);
 void           ure_rxeof(struct usbd_xfer *, void *, usbd_status);
 void           ure_txeof(struct usbd_xfer *, void *, usbd_status);
 int            ure_rx_list_init(struct ure_softc *);
@@ -763,23 +763,22 @@ void
 ure_start(struct ifnet *ifp)
 {
        struct ure_softc        *sc = ifp->if_softc;
+       struct ure_cdata        *cd = &sc->ure_cdata;
        struct mbuf             *m_head = NULL;
+       int                     idx;
 
        if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd) ||
            !(sc->ure_flags & URE_FLAG_LINK))
                return;
 
-       for (;;) {
-               if (sc->ure_cdata.tx_cnt == sc->ure_tx_list_cnt) {
-                       ifq_set_oactive(&ifp->if_snd);
-                       break;
-               }
-               
+       idx = cd->tx_prod;
+
+       while (cd->tx_cnt < sc->ure_tx_list_cnt) {
                m_head = ifq_deq_begin(&ifp->if_snd);
                if (m_head == NULL)
                        break;
 
-               if (ure_encap(sc, m_head)) {
+               if (ure_encap(sc, m_head, idx)) {
                        ifq_deq_rollback(&ifp->if_snd, m_head);
                        ifq_set_oactive(&ifp->if_snd);
                        break;
@@ -790,8 +789,13 @@ ure_start(struct ifnet *ifp)
                if (ifp->if_bpf)
                        bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
 #endif
-               ifp->if_timer = 5;
+               idx = (idx + 1) % sc->ure_tx_list_cnt;
+               cd->tx_cnt++;
        }
+
+       cd->tx_prod = idx;
+
+       ifp->if_timer = 5;
 }
 
 void
@@ -1727,7 +1731,7 @@ ure_rxeof(struct usbd_xfer *xfer, void *
                memcpy(&rxhdr, buf, sizeof(rxhdr));
                total_len -= sizeof(rxhdr);
 
-               pktlen = letoh32(rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK;
+               pktlen = lemtoh32(&rxhdr.ure_pktlen) & URE_RXPKT_LEN_MASK;
                DPRINTFN(4, ("next packet is %d bytes\n", pktlen));
                if (pktlen > total_len) {
                        DPRINTF(("not enough bytes left for next packet\n"));
@@ -1745,8 +1749,8 @@ ure_rxeof(struct usbd_xfer *xfer, void *
                        goto done;
                }
 
-               cflags = letoh32(rxhdr.ure_csum);
-               rxvlan = letoh32(rxhdr.ure_vlan);
+               cflags = lemtoh32(&rxhdr.ure_csum);
+               rxvlan = lemtoh32(&rxhdr.ure_vlan);
 
                /* Check IP header checksum. */
                if ((rxvlan & URE_RXPKT_IPV4) &&
@@ -1891,7 +1895,7 @@ ure_rx_list_init(struct ure_softc *sc)
 }
 
 int
-ure_encap(struct ure_softc *sc, struct mbuf *m)
+ure_encap(struct ure_softc *sc, struct mbuf *m, int idx)
 {
        struct ure_chain        *c;
        usbd_status             err;
@@ -1912,12 +1916,12 @@ ure_encap(struct ure_softc *sc, struct m
                cflags |= swap16(m->m_pkthdr.ether_vtag | URE_TXPKT_VLAN_TAG);
 #endif
 
-       c = &sc->ure_cdata.tx_chain[sc->ure_cdata.tx_prod];
+       c = &sc->ure_cdata.tx_chain[idx];
 
        /* header */
-       txhdr.ure_pktlen = htole32(m->m_pkthdr.len | URE_TXPKT_TX_FS |
+       htolem32(&txhdr.ure_pktlen, m->m_pkthdr.len | URE_TXPKT_TX_FS |
            URE_TXPKT_TX_LS);
-       txhdr.ure_vlan = htole32(cflags);
+       htolem32(&txhdr.ure_vlan, cflags);
        memcpy(c->uc_buf, &txhdr, sizeof(txhdr));
        frm_len = sizeof(txhdr);
 
@@ -1932,14 +1936,10 @@ ure_encap(struct ure_softc *sc, struct m
            frm_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, ure_txeof);
 
        err = usbd_transfer(c->uc_xfer);
-       if (err != 0 && err != USBD_IN_PROGRESS) {
+       if (err != USBD_IN_PROGRESS) {
                ure_stop(sc);
                return (EIO);
        }
-
-       sc->ure_cdata.tx_cnt++;
-       sc->ure_cdata.tx_prod = (sc->ure_cdata.tx_prod + 1) %
-           sc->ure_tx_list_cnt;
 
        return (0);
 }

Reply via email to