Call for hme(4) testers
Andrew Belashov
bel at orel.ru
Mon Feb 21 11:49:07 GMT 2005
Hello, Pyun!
Pyun YongHyeon wrote:
> Here is an optimized hme(4) patch. In my tests, now hme(4) outperforms
> i82558 based fxp on Ultra AXe.
>
> Details on changes:
> . move statistics code to mii_tick to reduce overhead in interrupt
> handler. It's not uncommon hme(4)'s interrupt handler is invoked
> at the rate of 2000+/sec and it's waste of time to update these
> statistics counters in the interrupt handler. It also simplifies
> adding DEVICE_POLLING code and reduces polling overheads.(Obtained
> from OpenBSD.)
> . Switch to bus_dmamap_load_mbuf_sg() for loading TX buffers. This
> saves one callback call and removes additional traverse of mbuf
> chains.
> . use imax() instead of max() since max() looks forward to seeing
> unsigned integer.
> . make sure to stop if_timer and disable interrupts in hme_stop.
> . free mbuf only after invoking bus_dmamap_sync.
> . simplify if_timer setup
> . don't leak mbuf when loading TX buffers were failed.
> . make sure to invoke hme_init_locked() to unfreeze DMA enine when
What is "DMA enine"?
> there are fatal errors.
>
> The primary intent of the patch is for detecting DMA freeze under
> high network loads I seen on AXe.(I never seen the freeze on Ultra2).
> It seems that it is very difficult for developers to reproduce the
> DMA freeze. I think it's more likely to happen on optimized driver
> since the driver is more faster than ever before and usually I saw
> the panic at 7.5 - 8 MB/s TX speeds.
>
> If there is no objections I'll committ it next week.
>
> Thanks.
I have patch collision with CURRENT:
$ patch -C </tmp/if_hme.diff.0221
Hmm... Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- sys/dev/hme/if_hme.c.orig Mon Jan 17 19:51:39 2005
|+++ sys/dev/hme/if_hme.c Mon Feb 21 18:59:25 2005
--------------------------
Patching file if_hme.c using Plan A...
Hunk #1 failed at 126.
Hunk #2 succeeded at 223 (offset 2 lines).
Hunk #3 succeeded at 439 (offset 2 lines).
Hunk #4 succeeded at 486 (offset 2 lines).
Hunk #5 succeeded at 566 (offset 12 lines).
Hunk #6 succeeded at 646 (offset 12 lines).
Hunk #7 succeeded at 918 (offset 12 lines).
Hunk #8 failed at 964.
Hunk #9 succeeded at 1094 (offset 12 lines).
Hunk #10 succeeded at 1127 (offset 12 lines).
Hunk #11 succeeded at 1164 (offset 12 lines).
Hunk #12 succeeded at 1288 (offset 12 lines).
Hunk #13 succeeded at 1316 (offset 12 lines).
2 out of 13 hunks failed--saving rejects to if_hme.c.rej
Hmm... The next patch looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- sys/dev/hme/if_hmevar.h.orig Thu Dec 16 18:57:37 2004
|+++ sys/dev/hme/if_hmevar.h Mon Feb 21 18:05:30 2005
--------------------------
Patching file if_hmevar.h using Plan A...
Hunk #1 succeeded at 100.
done
--
With Best Regards,
Andrew Belashov.
-------------- next part --------------
***************
*** 126,133 ****
static void hme_rxcksum(struct mbuf *, u_int32_t);
static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int);
- static void hme_txdma_callback(void *, bus_dma_segment_t *, int,
- bus_size_t, int);
devclass_t hme_devclass;
--- 126,131 ----
static void hme_rxcksum(struct mbuf *, u_int32_t);
static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int);
devclass_t hme_devclass;
***************
*** 1000,1049 ****
static int
hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
{
- struct hme_txdma_arg cba;
- struct hme_txdesc *td;
- int error, si, ri;
u_int32_t flags, cflags = 0;
- si = sc->sc_rb.rb_tdhead;
- if ((td = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL)
- return (-1);
if ((m0->m_pkthdr.csum_flags & sc->sc_csum_features) != 0)
hme_txcksum(m0, &cflags);
- td->htx_m = m0;
- cba.hta_sc = sc;
- cba.hta_htx = td;
- if ((error = bus_dmamap_load_mbuf(sc->sc_tdmatag, td->htx_dmamap,
- m0, hme_txdma_callback, &cba, 0)) != 0)
goto fail;
- if (cba.hta_ndescs == -1) {
- error = -1;
goto fail;
}
- bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap,
- BUS_DMASYNC_PREWRITE);
- STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q);
- STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, td, htx_q);
-
- /* Turn descriptor ownership to the hme, back to forth. */
- ri = sc->sc_rb.rb_tdhead;
- CTR2(KTR_HME, "hme_load_mbuf: next desc is %d (%#x)",
- ri, HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri));
- do {
- ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC;
- flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri) |
- HME_XD_OWN | cflags;
- CTR3(KTR_HME, "hme_load_mbuf: activating ri %d, si %d (%#x)",
- ri, si, flags);
- HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri, flags);
- } while (ri != si);
/* start the transmission. */
HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
return (0);
fail:
- bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap);
return (error);
}
--- 964,1028 ----
static int
hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
{
+ struct hme_txdesc *htx;
+ caddr_t txd;
+ int error;
+ int i, pci, si, ri, nseg;
u_int32_t flags, cflags = 0;
+ if ((htx = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL) {
+ error = -1;
+ goto fail;
+ }
if ((m0->m_pkthdr.csum_flags & sc->sc_csum_features) != 0)
hme_txcksum(m0, &cflags);
+ error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, htx->htx_dmamap,
+ m0, sc->sc_rb.rb_txsegs, &nseg, BUS_DMA_NOWAIT);
+ if (error != 0)
goto fail;
+ if (sc->sc_rb.rb_td_nbusy + nseg >= HME_NTXDESC) {
+ bus_dmamap_unload(sc->sc_tdmatag, htx->htx_dmamap);
+ error = -2;
goto fail;
}
+ bus_dmamap_sync(sc->sc_tdmatag, htx->htx_dmamap, BUS_DMASYNC_PREWRITE);
+ si = ri = sc->sc_rb.rb_tdhead;
+ txd = sc->sc_rb.rb_txd;
+ pci = sc->sc_pci;
+ for (i = 0; i < nseg; i++) {
+ /* Fill the ring entry. */
+ flags = HME_XD_ENCODE_TSIZE(sc->sc_rb.rb_txsegs[i].ds_len);
+ if (i == 0)
+ flags |= HME_XD_SOP | cflags;
+ else
+ flags |= HME_XD_OWN | cflags;
+ HME_XD_SETADDR(pci, txd, ri, sc->sc_rb.rb_txsegs[i].ds_addr);
+ HME_XD_SETFLAGS(pci, txd, ri, flags);
+ sc->sc_rb.rb_td_nbusy++;
+ htx->htx_lastdesc = ri;
+ ri = (ri + 1) % HME_NTXDESC;
+ }
+ sc->sc_rb.rb_tdhead = ri;
+
+ /* set EOP on the last descriptor */
+ ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC;
+ flags = HME_XD_GETFLAGS(pci, txd, ri);
+ flags |= HME_XD_EOP;
+ HME_XD_SETFLAGS(pci, txd, ri, flags);
+
+ /* Turn the first descriptor ownership to the hme */
+ flags = HME_XD_GETFLAGS(sc->sc_pci, txd, si);
+ flags |= HME_XD_OWN;
+ HME_XD_SETFLAGS(pci, txd, si, flags);
+ STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q);
+ STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, htx, htx_q);
+ htx->htx_m = m0;
/* start the transmission. */
HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
return (0);
fail:
return (error);
}
More information about the freebsd-sparc64
mailing list