summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hatm/if_hatm.c11
-rw-r--r--sys/dev/hatm/if_hatm_intr.c83
-rw-r--r--sys/dev/hatm/if_hatmvar.h9
3 files changed, 51 insertions, 52 deletions
diff --git a/sys/dev/hatm/if_hatm.c b/sys/dev/hatm/if_hatm.c
index a35544a..14d9491 100644
--- a/sys/dev/hatm/if_hatm.c
+++ b/sys/dev/hatm/if_hatm.c
@@ -316,10 +316,6 @@ hatm_destroy_smbufs(struct hatm_softc *sc)
if_printf(&sc->ifatm.ifnet,
"%s -- mbuf page=%u card buf %u\n",
__func__, i, b);
- if (MBUF_TST_BIT(pg->hdr.used, b))
- if_printf(&sc->ifatm.ifnet,
- "%s -- mbuf page=%u used buf %u\n",
- __func__, i, b);
}
bus_dmamap_unload(sc->mbuf_tag, pg->hdr.map);
bus_dmamap_destroy(sc->mbuf_tag, pg->hdr.map);
@@ -492,8 +488,6 @@ hatm_destroy(struct hatm_softc *sc)
cv_destroy(&sc->cv_rcclose);
cv_destroy(&sc->vcc_cv);
- mtx_destroy(&sc->mbuf0_mtx);
- mtx_destroy(&sc->mbuf1_mtx);
mtx_destroy(&sc->mtx);
}
@@ -1655,13 +1649,9 @@ hatm_attach(device_t dev)
sc->he622 = 0;
sc->ifatm.phy = &sc->utopia;
- SLIST_INIT(&sc->mbuf0_list);
- SLIST_INIT(&sc->mbuf1_list);
SLIST_INIT(&sc->tpd_free);
mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF);
- mtx_init(&sc->mbuf0_mtx, device_get_nameunit(dev), "HEb0", MTX_DEF);
- mtx_init(&sc->mbuf1_mtx, device_get_nameunit(dev), "HEb1", MTX_DEF);
cv_init(&sc->vcc_cv, "HEVCCcv");
cv_init(&sc->cv_rcclose, "RCClose");
@@ -2340,7 +2330,6 @@ hatm_stop(struct hatm_softc *sc)
for (i = 0; i < pg->hdr.nchunks; i++) {
if (MBUF_TST_BIT(pg->hdr.card, i)) {
MBUF_CLR_BIT(pg->hdr.card, i);
- MBUF_CLR_BIT(pg->hdr.used, 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 80347d1..9379026 100644
--- a/sys/dev/hatm/if_hatm_intr.c
+++ b/sys/dev/hatm/if_hatm_intr.c
@@ -83,6 +83,45 @@ CTASSERT(sizeof(((struct mbuf0_chunk *)NULL)->storage) >= MBUF0_SIZE);
CTASSERT(sizeof(((struct mbuf1_chunk *)NULL)->storage) >= MBUF1_SIZE);
CTASSERT(sizeof(struct tpd) <= HE_TPD_SIZE);
+static void hatm_mbuf_page_alloc(struct hatm_softc *sc, u_int group);
+
+/*
+ * Free an external mbuf to a list. We use atomic functions so that
+ * we don't need a mutex for the list.
+ */
+static __inline void
+hatm_ext_free(struct mbufx_free **list, struct mbufx_free *buf)
+{
+ for (;;) {
+ buf->link = *list;
+ if (atomic_cmpset_ptr(list, buf->link, buf))
+ break;
+ }
+}
+
+static __inline struct mbufx_free *
+hatm_ext_alloc(struct hatm_softc *sc, u_int g)
+{
+ struct mbufx_free *buf;
+
+ for (;;) {
+ if ((buf = sc->mbuf_list[g]) == NULL)
+ break;
+ if (atomic_cmpset_ptr(&sc->mbuf_list[g], buf, buf->link))
+ break;
+ }
+ if (buf == NULL) {
+ hatm_mbuf_page_alloc(sc, g);
+ for (;;) {
+ if ((buf = sc->mbuf_list[g]) == NULL)
+ break;
+ if (atomic_cmpset_ptr(&sc->mbuf_list[g], buf, buf->link))
+ break;
+ }
+ }
+ return (buf);
+}
+
/*
* Either the queue treshold was crossed or a TPD with the INTR bit set
* was transmitted.
@@ -141,7 +180,6 @@ hatm_mbuf_page_alloc(struct hatm_softc *sc, u_int group)
if ((pg = malloc(MBUF_ALLOC_SIZE, M_DEVBUF, M_NOWAIT)) == NULL)
return;
bzero(pg->hdr.card, sizeof(pg->hdr.card));
- bzero(pg->hdr.used, sizeof(pg->hdr.used));
err = bus_dmamap_create(sc->mbuf_tag, 0, &pg->hdr.map);
if (err != 0) {
@@ -172,8 +210,8 @@ hatm_mbuf_page_alloc(struct hatm_softc *sc, u_int group)
for (i = 0; i < MBUF0_PER_PAGE; i++, c++) {
c->hdr.pageno = sc->mbuf_npages;
c->hdr.chunkno = i;
- SLIST_INSERT_HEAD(&sc->mbuf0_list,
- (struct mbufx_free *)c, link);
+ hatm_ext_free(&sc->mbuf_list[0],
+ (struct mbufx_free *)c);
}
} else {
struct mbuf1_chunk *c;
@@ -185,8 +223,8 @@ hatm_mbuf_page_alloc(struct hatm_softc *sc, u_int group)
for (i = 0; i < MBUF1_PER_PAGE; i++, c++) {
c->hdr.pageno = sc->mbuf_npages;
c->hdr.chunkno = i;
- SLIST_INSERT_HEAD(&sc->mbuf1_list,
- (struct mbufx_free *)c, link);
+ hatm_ext_free(&sc->mbuf_list[1],
+ (struct mbufx_free *)c);
}
}
sc->mbuf_npages++;
@@ -201,10 +239,7 @@ hatm_mbuf0_free(void *buf, void *args)
struct hatm_softc *sc = args;
struct mbuf0_chunk *c = buf;
- mtx_lock(&sc->mbuf0_mtx);
- SLIST_INSERT_HEAD(&sc->mbuf0_list, (struct mbufx_free *)c, link);
- MBUF_CLR_BIT(sc->mbuf_pages[c->hdr.pageno]->hdr.used, c->hdr.chunkno);
- mtx_unlock(&sc->mbuf0_mtx);
+ hatm_ext_free(&sc->mbuf_list[0], (struct mbufx_free *)c);
}
static void
hatm_mbuf1_free(void *buf, void *args)
@@ -212,10 +247,7 @@ hatm_mbuf1_free(void *buf, void *args)
struct hatm_softc *sc = args;
struct mbuf1_chunk *c = buf;
- mtx_lock(&sc->mbuf1_mtx);
- SLIST_INSERT_HEAD(&sc->mbuf1_list, (struct mbufx_free *)c, link);
- MBUF_CLR_BIT(sc->mbuf_pages[c->hdr.pageno]->hdr.used, c->hdr.chunkno);
- mtx_unlock(&sc->mbuf1_mtx);
+ hatm_ext_free(&sc->mbuf_list[1], (struct mbufx_free *)c);
}
/*
@@ -231,19 +263,11 @@ hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, struct mbuf *m,
if (group == 0) {
struct mbuf0_chunk *buf0;
- mtx_lock(&sc->mbuf0_mtx);
- if ((cf = SLIST_FIRST(&sc->mbuf0_list)) == NULL) {
- hatm_mbuf_page_alloc(sc, group);
- if ((cf = SLIST_FIRST(&sc->mbuf0_list)) == NULL) {
- mtx_unlock(&sc->mbuf0_mtx);
- return (-1);
- }
- }
- SLIST_REMOVE_HEAD(&sc->mbuf0_list, link);
+ if ((cf = hatm_ext_alloc(sc, 0)) == NULL)
+ return (-1);
buf0 = (struct mbuf0_chunk *)cf;
pg = sc->mbuf_pages[buf0->hdr.pageno];
MBUF_SET_BIT(pg->hdr.card, buf0->hdr.chunkno);
- mtx_unlock(&sc->mbuf0_mtx);
m_extadd(m, (caddr_t)buf0, MBUF0_SIZE, hatm_mbuf0_free, sc,
M_PKTHDR, EXT_NET_DRV);
@@ -255,19 +279,11 @@ hatm_mbuf_alloc(struct hatm_softc *sc, u_int group, struct mbuf *m,
} else if (group == 1) {
struct mbuf1_chunk *buf1;
- mtx_lock(&sc->mbuf1_mtx);
- if ((cf = SLIST_FIRST(&sc->mbuf1_list)) == NULL) {
- hatm_mbuf_page_alloc(sc, group);
- if ((cf = SLIST_FIRST(&sc->mbuf1_list)) == NULL) {
- mtx_unlock(&sc->mbuf1_mtx);
- return (-1);
- }
- }
- SLIST_REMOVE_HEAD(&sc->mbuf1_list, link);
+ if ((cf = hatm_ext_alloc(sc, 1)) == NULL)
+ return (-1);
buf1 = (struct mbuf1_chunk *)cf;
pg = sc->mbuf_pages[buf1->hdr.pageno];
MBUF_SET_BIT(pg->hdr.card, buf1->hdr.chunkno);
- mtx_unlock(&sc->mbuf1_mtx);
m_extadd(m, (caddr_t)buf1, MBUF1_SIZE, hatm_mbuf1_free, sc,
M_PKTHDR, EXT_NET_DRV);
@@ -431,7 +447,6 @@ hatm_rx_buffer(struct hatm_softc *sc, u_int group, u_int handle)
m = c1->hdr.mbuf;
}
MBUF_CLR_BIT(sc->mbuf_pages[pageno]->hdr.card, chunkno);
- MBUF_SET_BIT(sc->mbuf_pages[pageno]->hdr.used, chunkno);
bus_dmamap_sync(sc->mbuf_tag, sc->mbuf_pages[pageno]->hdr.map,
BUS_DMASYNC_POSTREAD);
diff --git a/sys/dev/hatm/if_hatmvar.h b/sys/dev/hatm/if_hatmvar.h
index 694dad1..184d98b 100644
--- a/sys/dev/hatm/if_hatmvar.h
+++ b/sys/dev/hatm/if_hatmvar.h
@@ -239,7 +239,6 @@ SLIST_HEAD(tpd_list, tpd);
/* each allocated page has one of these structures at its very end. */
struct mbuf_page_hdr {
uint8_t card[32]; /* bitmap for on-card */
- uint8_t used[32]; /* bitmap for used but not on-card */
uint16_t nchunks; /* chunks on this page */
bus_dmamap_t map; /* the DMA MAP */
uint32_t phys; /* physical base address */
@@ -292,9 +291,8 @@ struct mbuf1_chunk {
};
struct mbufx_free {
- SLIST_ENTRY(mbufx_free) link;
+ struct mbufx_free *link;
};
-SLIST_HEAD(mbufx_free_list, mbufx_free);
/*==================================================================*/
@@ -413,10 +411,7 @@ struct hatm_softc {
bus_dma_tag_t mbuf_tag;
struct mbuf_page **mbuf_pages;
u_int mbuf_npages;
- struct mtx mbuf0_mtx;
- struct mbufx_free_list mbuf0_list;
- struct mtx mbuf1_mtx;
- struct mbufx_free_list mbuf1_list;
+ struct mbufx_free *mbuf_list[2];
/* mbuf cluster tracking and mapping for group 0 */
struct mbuf **lbufs; /* mbufs */
OpenPOWER on IntegriCloud