> Date: Wed, 18 Oct 2023 16:40:20 +0000 > From: Miod Vallat <m...@online.fr> > > I had the misfortune of hitting a KASSERT in dwge: > > panic: kernel diagnostic assertion "len > 0" failed: file > "/usr/src/sys/dev/fdt > /if_dwge.c", line 1102 > Stopped at panic+0x106: addi a0,zero,256 TID PID UID > PR > FLAGS PFLAGS CPU COMMAND > *405136 98879 1500 0x3 0 0 git > 301471 67731 0 0x14000 0x200 1 softnet0 > panic() at panic+0x106 > panic() at panic > dwge_rx_proc() at dwge_rx_proc+0x1d4 > dwge_intr() at dwge_intr+0x4e > plic_irq_dispatch() at plic_irq_dispatch+0xec > plic_irq_handler() at plic_irq_handler+0x56 > riscv_cpu_intr() at riscv_cpu_intr+0x22 > cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x7a > pmap_copy_page() at pmap_copy_page+0x94 > uvm_pagerealloc_multi() at uvm_pagerealloc_multi+0x24e > buf_realloc_pages() at buf_realloc_pages+0xa0 > buf_flip_high() at buf_flip_high+0x64 > bufcache_recover_dmapages() at bufcache_recover_dmapages+0x13a > buf_get() at buf_get+0xec > end trace frame: 0xffffffc04d9ac870, count: 0 > > The following diff should count the error and skirt the panic.
You probably hit a receive error and hit this code path because we don't check the error bit in the receive descriptor. I fixed this in dwqe(4) recently, and would prefer a similar fix here. The (untested) diff for that is attached here. We may still want to check the length on top of that (and make a similar change for dwqe(4)). I think I saw packets with the error bit set that had a length > 0 on dwqe(4) and this makes me suspect that it happens on dwge(4) as well. Index: dev/fdt/if_dwge.c =================================================================== RCS file: /cvs/src/sys/dev/fdt/if_dwge.c,v retrieving revision 1.19 diff -u -p -r1.19 if_dwge.c --- dev/fdt/if_dwge.c 15 Aug 2023 08:27:30 -0000 1.19 +++ dev/fdt/if_dwge.c 18 Oct 2023 22:29:16 -0000 @@ -214,6 +214,7 @@ struct dwge_desc { #define RDES0_OE (1 << 11) #define RDES0_SAF (1 << 13) #define RDES0_DE (1 << 14) +#define RDES0_ES (1 << 15) #define RDES0_FL_MASK 0x3fff #define RDES0_FL_SHIFT 16 #define RDES0_AFM (1 << 30) @@ -1097,15 +1098,20 @@ dwge_rx_proc(struct dwge_softc *sc) len, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); - /* Strip off CRC. */ - len -= ETHER_CRC_LEN; - KASSERT(len > 0); - m = rxb->tb_m; rxb->tb_m = NULL; - m->m_pkthdr.len = m->m_len = len; + if (rxd->sd_status & RDES0_ES) { + ifp->if_ierrors++; + m_freem(m); + } else { + /* Strip off CRC. */ + len -= ETHER_CRC_LEN; + KASSERT(len > 0); - ml_enqueue(&ml, m); + m->m_pkthdr.len = m->m_len = len; + + ml_enqueue(&ml, m); + } put++; if (sc->sc_rx_cons == (DWGE_NRXDESC - 1)) > > Index: if_dwge.c > =================================================================== > RCS file: /OpenBSD/src/sys/dev/fdt/if_dwge.c,v > retrieving revision 1.19 > diff -u -p -r1.19 if_dwge.c > --- if_dwge.c 15 Aug 2023 08:27:30 -0000 1.19 > +++ if_dwge.c 18 Oct 2023 16:37:59 -0000 > @@ -1099,13 +1101,15 @@ dwge_rx_proc(struct dwge_softc *sc) > > /* Strip off CRC. */ > len -= ETHER_CRC_LEN; > - KASSERT(len > 0); > - > - m = rxb->tb_m; > - rxb->tb_m = NULL; > - m->m_pkthdr.len = m->m_len = len; > + if (len <= 0) { > + ifp->if_ierrors++; > + } else { > + m = rxb->tb_m; > + rxb->tb_m = NULL; > + m->m_pkthdr.len = m->m_len = len; > > - ml_enqueue(&ml, m); > + ml_enqueue(&ml, m); > + } > > put++; > if (sc->sc_rx_cons == (DWGE_NRXDESC - 1)) > >