diff options
-rw-r--r-- | sys/dev/hatm/if_hatm.c | 11 | ||||
-rw-r--r-- | sys/dev/hatm/if_hatm_intr.c | 83 | ||||
-rw-r--r-- | sys/dev/hatm/if_hatmvar.h | 9 |
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 */ |