On Fri, Jan 28, 2011 at 09:03 +0100, Gabriel Linder wrote:
> On 01/27/11 09:13, Gabriel Linder wrote:
> >When booting 4.9-beta/amd64 without a network cable plugged, I get
> >a lot of splassert failures.
> >
> >After changing kern.splassert to 3 I was able to get the following
> >trace (get with dmesg after a reboot) :
> >
> >splassert: assertwaitok: want -1 have 1
> >Starting stack trace...
> >splassert_fail() at splassert_fail+0x55
> >assertwaitok() at assertwaitok+0x1c
> >pool_get() at pool_get+0x95
> >m_gethdr() at m_gethdr+0x3e
> >alc_newbuf() at alc_newbuf+0x39
> >alc_init_rx_ring() at alc_init_rx_ring+0x80
> >alc_init() at alc_init+0x2d
> >if_slowtimo() at if_slowtimo+0x5c
> >softclock() at softclock+0x291
> >softintr_dispatch() at softintr_dispatch+0x5d
> >Xsoftclock() at Xsoftclock+0x2d
> >--- interrupt ---
> >end trace frame: 0x0, count: 246
> >0x8:
> >End of stack trace.
> >Stopped at Debugger+0x5: leave
> >ddb{0}> Debugger() at Debugger+0x5
> >assertwaitok() at assertwaitok+0x1c
> >pool_get() at pool_get+0x95
> >m_gethdr() at m_gethdr+0x3e
> >alc_newbuf() at alc_newbuf+0x39
> >alc_init_rx_ring() at alc_init_rx_ring+0x80
> >alc_init() at alc_init+0x2d
> >if_slowtimo() at if_slowtimo+0x5c
> >softclock() at softclock+0x291
> >softintr_dispatch() at softintr_dispatch+0x5d
> >Xsoftclock() at Xsoftclock+0
> >
hi, if you haven't fixed it yet, here's a diff. it also fixes a
error/!error logic bug. could you please try it out?
alc_newbuf is always called from the interrupt context so it can't
sleep in any case.
Index: if_alc.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_alc.c,v
retrieving revision 1.9
diff -u -p -r1.9 if_alc.c
--- if_alc.c 29 Jan 2011 08:13:46 -0000 1.9
+++ if_alc.c 30 Jan 2011 13:32:59 -0000
@@ -104,7 +104,7 @@ void alc_mac_config(struct alc_softc *);
int alc_miibus_readreg(struct device *, int, int);
void alc_miibus_statchg(struct device *);
void alc_miibus_writereg(struct device *, int, int, int);
-int alc_newbuf(struct alc_softc *, struct alc_rxdesc *, int);
+int alc_newbuf(struct alc_softc *, struct alc_rxdesc *);
void alc_phy_down(struct alc_softc *);
void alc_phy_reset(struct alc_softc *);
void alc_reset(struct alc_softc *);
@@ -1552,16 +1552,16 @@ alc_txeof(struct alc_softc *sc)
}
int
-alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd, int init)
+alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd)
{
struct mbuf *m;
bus_dmamap_t map;
int error;
- MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
return (ENOBUFS);
- MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
+ MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
m_freem(m);
return (ENOBUFS);
@@ -1573,18 +1573,8 @@ alc_newbuf(struct alc_softc *sc, struct
sc->alc_cdata.alc_rx_sparemap, m, BUS_DMA_NOWAIT);
if (error != 0) {
- if (!error) {
- bus_dmamap_unload(sc->sc_dmat,
- sc->alc_cdata.alc_rx_sparemap);
- error = EFBIG;
- printf("%s: too many segments?!\n",
- sc->sc_dev.dv_xname);
- }
m_freem(m);
-
- if (init)
- printf("%s: can't load RX mbuf\n", sc->sc_dev.dv_xname);
-
+ printf("%s: can't load RX mbuf\n", sc->sc_dev.dv_xname);
return (error);
}
@@ -1707,7 +1697,7 @@ alc_rxeof(struct alc_softc *sc, struct r
rxd = &sc->alc_cdata.alc_rxdesc[rx_cons];
mp = rxd->rx_m;
/* Add a new receive buffer to the ring. */
- if (alc_newbuf(sc, rxd, 0) != 0) {
+ if (alc_newbuf(sc, rxd) != 0) {
ifp->if_iqdrops++;
/* Reuse Rx buffers. */
if (sc->alc_cdata.alc_rxhead != NULL)
@@ -2293,7 +2283,7 @@ alc_init_rx_ring(struct alc_softc *sc)
rxd = &sc->alc_cdata.alc_rxdesc[i];
rxd->rx_m = NULL;
rxd->rx_desc = &rd->alc_rx_ring[i];
- if (alc_newbuf(sc, rxd, 1) != 0)
+ if (alc_newbuf(sc, rxd) != 0)
return (ENOBUFS);
}