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.
This commit is contained in:
parent
d1f6e71f1d
commit
7672807356
|
@ -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[] = {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue