View Single Post
  #7   (View Single Post)  
Old 22nd July 2011
Logan Logan is offline
Real Name: Loganaden Velvindron
New User
 
Join Date: Jul 2011
Location: Mauritius
Posts: 3
Default

Hi,

OpenBSD 4.9 is going beta.

Try this diff: It reduces mbuf usage :-)

Index: smc83c170.c
================================================== =================
RCS file: /root/src/sys/dev/ic/smc83c170.c,v
retrieving revision 1.14
diff -u -r1.14 smc83c170.c
--- smc83c170.c 10 Aug 2009 20:29:54 -0000 1.14
+++ smc83c170.c 21 Jul 2011 17:06:49 -0000
@@ -83,6 +83,7 @@

void epic_reset(struct epic_softc *);
void epic_rxdrain(struct epic_softc *);
+void epic_fill_rx_ring(struct epic_softc *);
int epic_add_rxbuf(struct epic_softc *, int);
void epic_read_eeprom(struct epic_softc *, int, int, u_int16_t *);
void epic_set_mchash(struct epic_softc *);
@@ -286,7 +287,7 @@
ifp->if_watchdog = epic_watchdog;
IFQ_SET_MAXLEN(&ifp->if_snd, EPIC_NTXDESC - 1);
IFQ_SET_READY(&ifp->if_snd);
-
+ m_clsetwms(ifp, MCLBYTES, 2, EPIC_NRXDESC - 1);
ifp->if_capabilities = IFCAP_VLAN_MTU;

/*
@@ -621,7 +622,7 @@
* Check for receive interrupts.
*/
if (intstat & (INTSTAT_RCC | INTSTAT_RXE | INTSTAT_RQE)) {
- for (i = sc->sc_rxptr;; i = EPIC_NEXTRX(i)) {
+ for (i = sc->sc_rx_cons; sc->sc_rx_cnt > 0; i = EPIC_NEXTRX(i)) {
rxd = EPIC_CDRX(sc, i);
ds = EPIC_DSRX(sc, i);

@@ -637,6 +638,13 @@
break;
}

+ bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
+ ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
+
+ m = ds->ds_mbuf;
+ ds->ds_mbuf = NULL;
+ sc->sc_rx_cnt--;
/*
* Make sure the packet arrived intact. If an error
* occurred, update stats and reset the descriptor.
@@ -651,13 +659,10 @@
printf("%s: alignment error\n",
sc->sc_dev.dv_xname);
ifp->if_ierrors++;
- EPIC_INIT_RXDESC(sc, i);
+ m_freem(m);
continue;
}

- bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
- ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
-
/*
* The EPIC includes the CRC with every packet;
* trim it.
@@ -669,51 +674,16 @@
* Runt packet; drop it now.
*/
ifp->if_ierrors++;
- EPIC_INIT_RXDESC(sc, i);
+ m_freem(m);
bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
ds->ds_dmamap->dm_mapsize,
BUS_DMASYNC_PREREAD);
continue;
}

- /*
- * If the packet is small enough to fit in a
- * single header mbuf, allocate one and copy
- * the data into it. This greatly reduces
- * memory consumption when we receive lots
- * of small packets.
- *
- * Otherwise, we add a new buffer to the receive
- * chain. If this fails, we drop the packet and
- * recycle the old buffer.
- */
- if (epic_copy_small != 0 && len <= MHLEN) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- goto dropit;
- memcpy(mtod(m, caddr_t),
- mtod(ds->ds_mbuf, caddr_t), len);
- EPIC_INIT_RXDESC(sc, i);
- bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0,
- ds->ds_dmamap->dm_mapsize,
- BUS_DMASYNC_PREREAD);
- } else {
- m = ds->ds_mbuf;
- if (epic_add_rxbuf(sc, i) != 0) {
- dropit:
- ifp->if_ierrors++;
- EPIC_INIT_RXDESC(sc, i);
- bus_dmamap_sync(sc->sc_dmat,
- ds->ds_dmamap, 0,
- ds->ds_dmamap->dm_mapsize,
- BUS_DMASYNC_PREREAD);
- continue;
- }
- }
-
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
-
+ m->m_data += 2;
#if NBPFILTER > 0
/*
* Pass this up to any BPF listeners, but only
@@ -729,20 +699,16 @@
}

/* Update the receive pointer. */
- sc->sc_rxptr = i;
-
+ sc->sc_rx_cons = i;
+ epic_fill_rx_ring(sc);
/*
* Check for receive queue underflow.
*/
if (intstat & INTSTAT_RQE) {
- printf("%s: receiver queue empty\n",
- sc->sc_dev.dv_xname);
/*
* Ring is already built; just restart the
* receiver.
*/
- bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_PRCDAR,
- EPIC_CDRXADDR(sc, sc->sc_rxptr));
bus_space_write_4(sc->sc_st, sc->sc_sh, EPIC_COMMAND,
COMMAND_RXQUEUED | COMMAND_START_RX);
}
@@ -908,9 +874,8 @@
bus_space_tag_t st = sc->sc_st;
bus_space_handle_t sh = sc->sc_sh;
struct epic_txdesc *txd;
- struct epic_descsoft *ds;
u_int32_t genctl, reg0;
- int i, error = 0;
+ int i;

/*
* Cancel any pending I/O.
@@ -998,24 +963,12 @@
* Initialize the receive descriptor ring.
*/
for (i = 0; i < EPIC_NRXDESC; i++) {
- ds = EPIC_DSRX(sc, i);
- if (ds->ds_mbuf == NULL) {
- if ((error = epic_add_rxbuf(sc, i)) != 0) {
- printf("%s: unable to allocate or map rx "
- "buffer %d error = %d\n",
- sc->sc_dev.dv_xname, i, error);
- /*
- * XXX Should attempt to run with fewer receive
- * XXX buffers instead of just failing.
- */
- epic_rxdrain(sc);
- goto out;
- }
- } else
- EPIC_INIT_RXDESC(sc, i);
+ sc->sc_control_data->ecd_rxdescs[i].er_bufaddr = 0;
+ sc->sc_control_data->ecd_rxdescs[i].er_control = 0;
+ sc->sc_control_data->ecd_rxdescs[i].er_rxstatus = 0;
+ sc->sc_control_data->ecd_rxdescs[i].er_nextdesc = 0;
}
- sc->sc_rxptr = 0;
-
+ epic_fill_rx_ring(sc);
/*
* Initialize the interrupt mask and enable interrupts.
*/
@@ -1028,7 +981,7 @@
bus_space_write_4(st, sh, EPIC_PTCDAR,
EPIC_CDTXADDR(sc, EPIC_NEXTTX(sc->sc_txlast)));
bus_space_write_4(st, sh, EPIC_PRCDAR,
- EPIC_CDRXADDR(sc, sc->sc_rxptr));
+ EPIC_CDRXADDR(sc, sc->sc_rx_prod));

/*
* Set the EPIC in motion.
@@ -1052,10 +1005,7 @@
*/
epic_start(ifp);

- out:
- if (error)
- printf("%s: interface not running\n", sc->sc_dev.dv_xname);
- return (error);
+ return (0);
}

/*
@@ -1075,6 +1025,7 @@
ds->ds_mbuf = NULL;
}
}
+ sc->sc_rx_prod = sc->sc_rx_cons = sc->sc_rx_cnt = 0;
}

/*
@@ -1213,6 +1164,15 @@
#undef EEPROM_WAIT_READY
}

+void
+epic_fill_rx_ring(struct epic_softc *sc)
+{
+ while(sc->sc_rx_cnt < EPIC_NRXDESC) {
+ if(epic_add_rxbuf(sc, sc->sc_rx_prod))
+ break;
+ }
+}
+
/*
* Add a receive buffer to the indicated descriptor.
*/
@@ -1223,23 +1183,14 @@
struct mbuf *m;
int error;

- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
+ m = MCLGETI(NULL, M_DONTWAIT, &sc->sc_arpcom.ac_if, MCLBYTES);
+ if (!m)
return (ENOBUFS);
-
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- m_freem(m);
- return (ENOBUFS);
- }
-
- if (ds->ds_mbuf != NULL)
- bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap);
+ m->m_len = m->m_pkthdr.len = MCLBYTES;

ds->ds_mbuf = m;

- error = bus_dmamap_load(sc->sc_dmat, ds->ds_dmamap,
- m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
+ error = bus_dmamap_load_mbuf(sc->sc_dmat, ds->ds_dmamap, m,
BUS_DMA_READ|BUS_DMA_NOWAIT);
if (error) {
printf("%s: can't load rx DMA map %d, error = %d\n",
@@ -1251,6 +1202,8 @@
ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);

EPIC_INIT_RXDESC(sc, idx);
+ sc->sc_rx_prod = EPIC_NEXTRX(sc->sc_rx_prod);
+ sc->sc_rx_cnt++;

return (0);
}
Index: smc83c170var.h
================================================== =================
RCS file: /root/src/sys/dev/ic/smc83c170var.h,v
retrieving revision 1.3
diff -u -r1.3 smc83c170var.h
--- smc83c170var.h 10 Aug 2009 20:29:54 -0000 1.3
+++ smc83c170var.h 21 Jul 2011 17:06:49 -0000
@@ -128,7 +128,9 @@
int sc_txdirty; /* first dirty TX descriptor */
int sc_txlast; /* last used TX descriptor */

- int sc_rxptr; /* next ready RX descriptor */
+ int sc_rx_cnt;
+ int sc_rx_prod;
+ int sc_rx_cons;

u_int sc_serinst; /* ifmedia instance for serial mode */
};
@@ -167,7 +169,6 @@
* so that the payload after the Ethernet header is aligned \
* to a 4 byte boundary. \
*/ \
- __m->m_data = __m->m_ext.ext_buf + 2; \
__rxd->er_bufaddr = __ds->ds_dmamap->dm_segs[0].ds_addr + 2; \
__rxd->er_control = RXCTL_BUFLENGTH(__m->m_ext.ext_size - 2); \
__rxd->er_rxstatus = ER_RXSTAT_OWNER; \
Reply With Quote