summaryrefslogtreecommitdiffstats
path: root/sys/dev/hatm
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2003-10-29 12:59:44 +0000
committerharti <harti@FreeBSD.org>2003-10-29 12:59:44 +0000
commit568c57f368a5b09aa3cac9b6d7ddb6fae11059c0 (patch)
tree9d42396102479ef0a920fb92a586c9ed15b548c1 /sys/dev/hatm
parent36edae8e0d6caa4c38b5624886e0b8a21fc77870 (diff)
downloadFreeBSD-src-568c57f368a5b09aa3cac9b6d7ddb6fae11059c0.zip
FreeBSD-src-568c57f368a5b09aa3cac9b6d7ddb6fae11059c0.tar.gz
Get rid of the mutexes for the exernal buffer free lists. Use
atomic instructions instead. Remove the stuff used to track whether an external mbuf travels through the system. This is temporary only and will come back soon.
Diffstat (limited to 'sys/dev/hatm')
-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