summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-10-29 13:14:39 +0000
committerharti <harti@FreeBSD.org>2003-10-29 13:14:39 +0000
commite0d0a97b8fc62bbf8d84b4ea74d6bf8673dfa51c (patch)
tree88eb2eb0b8a7880f39a0fcc057ebb85003e7a634
parent568c57f368a5b09aa3cac9b6d7ddb6fae11059c0 (diff)
downloadFreeBSD-src-e0d0a97b8fc62bbf8d84b4ea74d6bf8673dfa51c.zip
FreeBSD-src-e0d0a97b8fc62bbf8d84b4ea74d6bf8673dfa51c.tar.gz
Defer allocation of the actual receive mbuf until the external buffer
is returned from the card to the driver. Add a counter that shows how many times this allocation has failed. Note, that we could even further delay the allocation of the mbuf until we know, that we need it (there are no receive errors and the connection is open). This will be done in a later commit. Print the new statistics field in atmconfig.
-rw-r--r--sbin/atm/atmconfig/diag.c1
-rw-r--r--sys/dev/hatm/if_hatm.c1
-rw-r--r--sys/dev/hatm/if_hatm_intr.c50
-rw-r--r--sys/dev/hatm/if_hatm_rx.c4
-rw-r--r--sys/dev/hatm/if_hatmvar.h4
5 files changed, 31 insertions, 29 deletions
diff --git a/sbin/atm/atmconfig/diag.c b/sbin/atm/atmconfig/diag.c
index 8e76d7d..acd83bb 100644
--- a/sbin/atm/atmconfig/diag.c
+++ b/sbin/atm/atmconfig/diag.c
@@ -153,6 +153,7 @@ static const char *const print_stats_he[] = {
"oec:",
"dcc:",
"cec:",
+ "no_rcv_mbuf:",
NULL
};
static const char *const print_stats_eni[] = {
diff --git a/sys/dev/hatm/if_hatm.c b/sys/dev/hatm/if_hatm.c
index 14d9491..7a97629 100644
--- a/sys/dev/hatm/if_hatm.c
+++ b/sys/dev/hatm/if_hatm.c
@@ -2332,7 +2332,6 @@ hatm_stop(struct hatm_softc *sc)
MBUF_CLR_BIT(pg->hdr.card, i);
ch = (struct mbuf_chunk_hdr *) ((char *)pg +
i * pg->hdr.chunksize + pg->hdr.hdroff);
- m_freem(ch->mbuf);
}
}
}
diff --git a/sys/dev/hatm/if_hatm_intr.c b/sys/dev/hatm/if_hatm_intr.c
index 9379026..cf2bfd3 100644
--- a/sys/dev/hatm/if_hatm_intr.c
+++ b/sys/dev/hatm/if_hatm_intr.c
@@ -254,8 +254,8 @@ hatm_mbuf1_free(void *buf, void *args)
* Allocate an external mbuf storage
*/
static int
-hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, struct mbuf *m,
- uint32_t *phys, uint32_t *handle)
+hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, uint32_t *phys,
+ uint32_t *handle)
{
struct mbufx_free *cf;
struct mbuf_page *pg;
@@ -269,12 +269,9 @@ hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, struct mbuf *m,
pg = sc->mbuf_pages[buf0->hdr.pageno];
MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno);
- m_extadd(m, (caddr_t)buf0, MBUF0_SIZE, hatm_mbuf0_free, sc,
- M_PKTHDR, EXT_NET_DRV);
- m->m_data += MBUF0_OFFSET;
- buf0->hdr.mbuf = m;
-
*handle = MBUF_MAKE_HANDLE(buf0->hdr.pageno, buf0->hdr.chunkno);
+ *phys = pg->hdr.phys + buf0->hdr.chunkno * MBUF0_CHUNK +
+ MBUF0_OFFSET;
} else if (group == 1) {
struct mbuf1_chunk *buf1;
@@ -285,17 +282,13 @@ hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, struct mbuf *m,
pg = sc->mbuf_pages[buf1->hdr.pageno];
MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno);
- m_extadd(m, (caddr_t)buf1, MBUF1_SIZE, hatm_mbuf1_free, sc,
- M_PKTHDR, EXT_NET_DRV);
- m->m_data += MBUF1_OFFSET;
- buf1->hdr.mbuf = m;
-
*handle = MBUF_MAKE_HANDLE(buf1->hdr.pageno, buf1->hdr.chunkno);
+ *phys = pg->hdr.phys + buf1->hdr.chunkno * MBUF1_CHUNK +
+ MBUF1_OFFSET;
} else
return (-1);
- *phys = pg->hdr.phys + (mtod(m, char *) - (char *)pg);
bus_dmamap_sync(sc->mbuf_tag, pg->hdr.map, BUS_DMASYNC_PREREAD);
return (0);
@@ -341,8 +334,8 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large,
if (ntail == rbp->head)
break;
- /* allocate the MBUF */
if (large) {
+ /* allocate the MBUF */
if ((m = m_getcl(M_DONTWAIT, MT_DATA,
M_PKTHDR)) == NULL) {
if_printf(&sc->ifatm.ifnet,
@@ -372,12 +365,8 @@ he_intr_rbp(struct hatm_softc *sc, struct herbp *rbp, u_int large,
sc->lbufs_next = 0;
} else {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- if_printf(&sc->ifatm.ifnet, "no mbufs\n");
- break;
- }
- if (hatm_mbuf_alloc(sc, group, m,
+ m = NULL;
+ if (hatm_mbuf_alloc(sc, group,
&rbp->rbp[rbp->tail].phys,
&rbp->rbp[rbp->tail].handle)) {
m_freem(m);
@@ -420,10 +409,13 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle)
}
MBUF_PARSE_HANDLE(handle, pageno, chunkno);
+ MBUF_CLR_BIT(sc->mbuf_pages[pageno]->hdr.card, chunkno);
DBG(sc, RX, ("RX group=%u handle=%x page=%u chunk=%u", group, handle,
pageno, chunkno));
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+
if (group == 0) {
struct mbuf0_chunk *c0;
@@ -433,7 +425,12 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle)
KASSERT(c0->hdr.chunkno == chunkno, ("chunkno = %u/%u",
c0->hdr.chunkno, chunkno));
- m = c0->hdr.mbuf;
+ if (m != NULL) {
+ m_extadd(m, (void *)c0, MBUF0_SIZE,
+ hatm_mbuf0_free, sc, M_PKTHDR, EXT_NET_DRV);
+ m->m_data += MBUF0_OFFSET;
+ } else
+ hatm_mbuf0_free(c0, sc);
} else {
struct mbuf1_chunk *c1;
@@ -444,12 +441,13 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle)
KASSERT(c1->hdr.chunkno == chunkno, ("chunkno = %u/%u",
c1->hdr.chunkno, chunkno));
- m = c1->hdr.mbuf;
+ if (m != NULL) {
+ m_extadd(m, (void *)c1, MBUF1_SIZE,
+ hatm_mbuf1_free, sc, M_PKTHDR, EXT_NET_DRV);
+ m->m_data += MBUF1_OFFSET;
+ } else
+ hatm_mbuf1_free(c1, sc);
}
- MBUF_CLR_BIT(sc->mbuf_pages[pageno]->hdr.card, chunkno);
-
- bus_dmamap_sync(sc->mbuf_tag, sc->mbuf_pages[pageno]->hdr.map,
- BUS_DMASYNC_POSTREAD);
return (m);
}
diff --git a/sys/dev/hatm/if_hatm_rx.c b/sys/dev/hatm/if_hatm_rx.c
index 15e568d..f42e821 100644
--- a/sys/dev/hatm/if_hatm_rx.c
+++ b/sys/dev/hatm/if_hatm_rx.c
@@ -116,6 +116,10 @@ hatm_rx(struct hatm_softc *sc, u_int cid, u_int flags, struct mbuf *m0,
}
goto drop;
}
+ if (m0 == NULL) {
+ sc->istats.no_rcv_mbuf++;
+ return;
+ }
if ((m0->m_len = len) == 0) {
sc->istats.empty_hbuf++;
diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h
index 184d98b..d821923 100644
--- a/sys/dev/hatm/if_hatmvar.h
+++ b/sys/dev/hatm/if_hatmvar.h
@@ -62,6 +62,7 @@ struct istats {
uint32_t oec;
uint32_t dcc;
uint32_t cec;
+ uint32_t no_rcv_mbuf;
};
/* Card memory layout parameters */
@@ -270,9 +271,8 @@ struct mbuf_page {
#define MBUF_LARGE_FLAG (1 << 20)
-/* chunks have the following structure at the end */
+/* chunks have the following structure at the end (4 byte) */
struct mbuf_chunk_hdr {
- struct mbuf *mbuf;
uint16_t pageno;
uint16_t chunkno;
};
OpenPOWER on IntegriCloud