OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
MCLGETI support for xl(4)

From: Loganaden Velvindron (loganadengmail.com)
Date: Tue Sep 14 2010 - 15:31:33 CDT


Greetings,

With help from dlg, claudio, oga, miod & weerd, I've been trying to
write
to get mclgeti support for xl(4).

It's been working fine on -current for quite some time.

I've tried flooding it with tcpbench, ping -f, and siege.

I'm looking for feedback on how I can improve it.

Here's the diff:

xlreg.h

Index: src/sys/dev/ic/xlreg.h
===================================================================
RCS file: /cvs/src/sys/dev/ic/xlreg.h,v
retrieving revision 1.24
diff -u -p -r1.24 xlreg.h
--- src/sys/dev/ic/xlreg.h 7 Sep 2010 16:21:43 -0000 1.24
+++ src/sys/dev/ic/xlreg.h 12 Sep 2010 06:33:39 -0000
-480,7 +480,10 struct xl_chain_data {
        struct xl_chain_onefrag xl_rx_chain[XL_RX_LIST_CNT];
        struct xl_chain xl_tx_chain[XL_TX_LIST_CNT];
 
- struct xl_chain_onefrag *xl_rx_head;
+ struct xl_chain_onefrag *xl_rx_cons;
+ struct xl_chain_onefrag *xl_rx_prod;
+ int xl_rx_cnt;
+
 
        /* 3c90x "boomerang" queuing stuff */
        struct xl_chain *xl_tx_head;

xl.c

Index: src/sys/dev/ic/xl.c
===================================================================
RCS file: /cvs/src/sys/dev/ic/xl.c,v
retrieving revision 1.96
diff -u -p -r1.96 xl.c
--- src/sys/dev/ic/xl.c 7 Sep 2010 16:21:43 -0000 1.96
+++ src/sys/dev/ic/xl.c 12 Sep 2010 10:49:32 -0000
-180,6 +180,7 void xl_iff(struct xl_softc *);
 void xl_iff_90x(struct xl_softc *);
 void xl_iff_905b(struct xl_softc *);
 int xl_list_rx_init(struct xl_softc *);
+void xl_fill_rx_ring(struct xl_softc *);
 int xl_list_tx_init(struct xl_softc *);
 int xl_list_tx_init_90xB(struct xl_softc *);
 void xl_wait(struct xl_softc *);
-1076,8 +1077,8 xl_list_rx_init(struct xl_softc *sc)
        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                cd->xl_rx_chain[i].xl_ptr =
                        (struct xl_list_onefrag *)&ld->xl_rx_list[i];
- if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
- return(ENOBUFS);
+ /*if (xl_newbuf(sc, &cd->xl_rx_chain[i]) == ENOBUFS)
+ return(ENOBUFS);*/
                if (i == (XL_RX_LIST_CNT - 1))
                        n = 0;
                else
-1088,11 +1089,33 xl_list_rx_init(struct xl_softc *sc)
                ld->xl_rx_list[i].xl_next = htole32(next);
        }
 
- cd->xl_rx_head = &cd->xl_rx_chain[0];
-
+ cd->xl_rx_prod = cd->xl_rx_cons = &cd->xl_rx_chain[0];
+ cd->xl_rx_cnt = 0;
+ xl_fill_rx_ring(sc);
        return (0);
 }
 
+void
+xl_fill_rx_ring(struct xl_softc *sc)
+{
+ struct xl_chain_data *cd;
+ struct xl_list_data *ld;
+
+ cd = &sc->xl_cdata;
+ ld = sc->xl_ldata;
+
+ while (cd->xl_rx_cnt < XL_RX_LIST_CNT) {
+ if (xl_newbuf(sc, cd->xl_rx_prod) == ENOBUFS){
+ /*printf("Not filling");*/
+ break;
+ }
+ cd->xl_rx_prod = cd->xl_rx_prod->xl_next;
+ cd->xl_rx_cnt++;
+ /*printf("filling works %d",cd->xl_rx_cnt);*/
+ }
+}
+
+
 /*
  * Initialize an RX descriptor and attach an MBUF cluster.
  */
-1102,7 +1125,7 xl_newbuf(struct xl_softc *sc, struct xl
        struct mbuf *m_new = NULL;
        bus_dmamap_t map;
 
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
+ /*MGETHDR(m_new, M_DONTWAIT, MT_DATA);
        if (m_new == NULL)
                return (ENOBUFS);
 
-1110,6 +1133,13 xl_newbuf(struct xl_softc *sc, struct xl
        if (!(m_new->m_flags & M_EXT)) {
                m_freem(m_new);
                return (ENOBUFS);
+ }*/
+
+ m_new = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+
+ if (!m_new){
+ /*printf("\n no mbufs");*/
+ return (ENOBUFS);
        }
 
        m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
-1119,17 +1149,24 xl_newbuf(struct xl_softc *sc, struct xl
                return (ENOBUFS);
        }
 
+
+ /*if (bus_dmamap_load_mbuf(sc->sc_dmat, c->map, m_new,
BUS_DMA_NOWAIT)){
+ m_free(m_new);
+ return (ENOBUFS);
+ }*/
+
+
        /* sync the old map, and unload it (if necessary) */
        if (c->map->dm_nsegs != 0) {
                bus_dmamap_sync(sc->sc_dmat, c->map,
                    0, c->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
                bus_dmamap_unload(sc->sc_dmat, c->map);
        }
-
+
        map = c->map;
        c->map = sc->sc_rx_sparemap;
        sc->sc_rx_sparemap = map;
-
+
        /* Force longword alignment for packet payload. */
        m_adj(m_new, ETHER_ALIGN);
 
-1156,8 +1193,8 xl_rx_resync(struct xl_softc *sc)
        struct xl_chain_onefrag *pos;
        int i;
 
- pos = sc->xl_cdata.xl_rx_head;
-
+ pos = sc->xl_cdata.xl_rx_cons;
+ printf("\n resync");
        for (i = 0; i < XL_RX_LIST_CNT; i++) {
                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                    ((caddr_t)pos->xl_ptr - sc->sc_listkva),
-1172,8 +1209,8 xl_rx_resync(struct xl_softc *sc)
        if (i == XL_RX_LIST_CNT)
                return (0);
 
- sc->xl_cdata.xl_rx_head = pos;
-
+ sc->xl_cdata.xl_rx_cons = pos;
+ /*xl_fill_rx_ring(sc);*/
        return (EAGAIN);
 }
 
-1195,12 +1232,15 xl_rxeof(struct xl_softc *sc)
 
 again:
 
- while ((rxstat =
letoh32(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))
- != 0) {
- cur_rx = sc->xl_cdata.xl_rx_head;
- sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
+ while ((rxstat =
letoh32(sc->xl_cdata.xl_rx_cons->xl_ptr->xl_status))
+ != 0 && sc->xl_cdata.xl_rx_cnt > 0) {
+ cur_rx = sc->xl_cdata.xl_rx_cons;
+ m = cur_rx->xl_mbuf;
+ cur_rx->xl_mbuf = NULL;
+ sc->xl_cdata.xl_rx_cons = cur_rx->xl_next;
+ sc->xl_cdata.xl_rx_cnt--;
                total_len = rxstat & XL_RXSTAT_LENMASK;
-
+ /*printf("\n RX_CNT %d",sc->xl_cdata.xl_rx_cnt);*/
                bus_dmamap_sync(sc->sc_dmat, sc->sc_listmap,
                    ((caddr_t)cur_rx->xl_ptr - sc->sc_listkva),
                    sizeof(struct xl_list),
-1222,8 +1262,10 again:
                 * comes up in the ring.
                 */
                if (rxstat & XL_RXSTAT_UP_ERROR) {
+ printf("\n error occured");
                        ifp->if_ierrors++;
                        cur_rx->xl_ptr->xl_status = htole32(0);
+ m_freem(m);
                        continue;
                }
 
-1237,12 +1279,16 again:
                            "packet dropped\n", sc->sc_dev.dv_xname);
                        ifp->if_ierrors++;
                        cur_rx->xl_ptr->xl_status = htole32(0);
+ m_freem(m);
                        continue;
                }
 
                /* No errors; receive the packet. */
- m = cur_rx->xl_mbuf;
-
+ /*m = cur_rx->xl_mbuf;*/
+ /*bus_dmamap_sync(sc->sc_dmat, cur_rx->map, 0,
+ cur_rx->map->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, cur_rx->map);
+ */
                /*
                 * Try to conjure up a new mbuf cluster. If that
                 * fails, it means we have an out of memory condition and
-1250,11 +1296,11 again:
                 * result in a lost packet, but there's little else we
                 * can do in this situation.
                 */
- if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
+ /*if (xl_newbuf(sc, cur_rx) == ENOBUFS) {
                        ifp->if_ierrors++;
                        cur_rx->xl_ptr->xl_status = htole32(0);
                        continue;
- }

+ }*/
 
                ifp->if_ipackets++;
                m->m_pkthdr.rcvif = ifp;
-1286,7 +1332,7 again:
 
                ether_input_mbuf(ifp, m);
        }
-
+ xl_fill_rx_ring(sc);
        /*
         * Handle the 'end of channel' condition. When the upload
         * engine hits the end of the RX ring, it will stall. This
-1301,15 +1347,20 again:
         */
        if (CSR_READ_4(sc, XL_UPLIST_PTR) == 0 ||
                CSR_READ_4(sc, XL_UPLIST_STATUS) & XL_PKTSTAT_UP_STALLED) {
+ /*printf("\n Upstall");*/
                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
                xl_wait(sc);
- CSR_WRITE_4(sc, XL_UPLIST_PTR,
+ /*CSR_WRITE_4(sc, XL_UPLIST_PTR,
                    sc->sc_listmap->dm_segs[0].ds_addr +
                    offsetof(struct xl_list_data, xl_rx_list[0]));
- sc->xl_cdata.xl_rx_head = &sc->xl_cdata.xl_rx_chain[0];
+ sc->xl_cdata.xl_rx_cons = &sc->xl_cdata.xl_rx_chain[0];*/
                CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
+ xl_fill_rx_ring(sc);
                goto again;
        }
+ /*else
+ xl_fill_rx_ring(sc);
+ */
 }
 
 /*
-1519,10 +1570,10 xl_intr(void *arg)
 
                        curpkts = ifp->if_ipackets;
                        xl_rxeof(sc);
- if (curpkts == ifp->if_ipackets) {
+ /*if (curpkts == ifp->if_ipackets) {
                                while (xl_rx_resync(sc))
                                        xl_rxeof(sc);
- }
+ }*/
                }
 
                if (status & XL_STAT_DOWN_COMPLETE) {
-2677,7 +2728,7 xl_attach(struct xl_softc *sc)
         */
        if_attach(ifp);
        ether_ifattach(ifp);
-
+ m_clsetwms(ifp, MCLBYTES, 2, XL_RX_LIST_CNT - 1);
        sc->sc_sdhook = shutdownhook_establish(xl_shutdown, sc);
 }