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);
}