summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2015-04-08 00:49:53 +0000
committernp <np@FreeBSD.org>2015-04-08 00:49:53 +0000
commitc95079747b8ce6760dbf403d7a0a1c5617f3f508 (patch)
tree58d538a1aa123c12b4668d0299b0933c72540894 /sys/dev
parent8b138d1fe9fc0a8bb72e0e25d2adfe85d67cf54e (diff)
downloadFreeBSD-src-c95079747b8ce6760dbf403d7a0a1c5617f3f508.zip
FreeBSD-src-c95079747b8ce6760dbf403d7a0a1c5617f3f508.tar.gz
MFC r276729, r276775.
r276729: cxgbe/tom: use vmem(9) as the DDP page pod allocator. r276775: cxgbe/tom: allocate page pod addresses instead of ppod#.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/cxgbe/tom/t4_ddp.c104
-rw-r--r--sys/dev/cxgbe/tom/t4_tom.h18
2 files changed, 29 insertions, 93 deletions
diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c
index 78e80d2..3b99a6e 100644
--- a/sys/dev/cxgbe/tom/t4_ddp.c
+++ b/sys/dev/cxgbe/tom/t4_ddp.c
@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
#define PPOD_SZ(n) ((n) * sizeof(struct pagepod))
#define PPOD_SIZE (PPOD_SZ(1))
-/* XXX: must match A_ULP_RX_TDDP_PSZ */
+/* XXX: must match A_ULP_RX_TDDP_PSZ */
static int t4_ddp_pgsz[] = {4096, 4096 << 2, 4096 << 4, 4096 << 6};
#if 0
@@ -98,74 +98,26 @@ t4_dump_tcb(struct adapter *sc, int tid)
#define MAX_DDP_BUFFER_SIZE (M_TCB_RX_DDP_BUF0_LEN)
static int
-alloc_ppods(struct tom_data *td, int n, struct ppod_region *pr)
+alloc_ppods(struct tom_data *td, int n, u_int *ppod_addr)
{
- int ppod;
+ vmem_addr_t v;
+ int rc;
- KASSERT(n > 0, ("%s: nonsense allocation (%d)", __func__, n));
+ MPASS(n > 0);
- mtx_lock(&td->ppod_lock);
- if (n > td->nppods_free) {
- mtx_unlock(&td->ppod_lock);
- return (-1);
- }
+ rc = vmem_alloc(td->ppod_arena, PPOD_SZ(n), M_NOWAIT | M_FIRSTFIT, &v);
+ *ppod_addr = (u_int)v;
- if (td->nppods_free_head >= n) {
- td->nppods_free_head -= n;
- ppod = td->nppods_free_head;
- TAILQ_INSERT_HEAD(&td->ppods, pr, link);
- } else {
- struct ppod_region *p;
-
- ppod = td->nppods_free_head;
- TAILQ_FOREACH(p, &td->ppods, link) {
- ppod += p->used + p->free;
- if (n <= p->free) {
- ppod -= n;
- p->free -= n;
- TAILQ_INSERT_AFTER(&td->ppods, p, pr, link);
- goto allocated;
- }
- }
-
- if (__predict_false(ppod != td->nppods)) {
- panic("%s: ppods TAILQ (%p) corrupt."
- " At %d instead of %d at the end of the queue.",
- __func__, &td->ppods, ppod, td->nppods);
- }
-
- mtx_unlock(&td->ppod_lock);
- return (-1);
- }
-
-allocated:
- pr->used = n;
- pr->free = 0;
- td->nppods_free -= n;
- mtx_unlock(&td->ppod_lock);
-
- return (ppod);
+ return (rc);
}
static void
-free_ppods(struct tom_data *td, struct ppod_region *pr)
+free_ppods(struct tom_data *td, u_int ppod_addr, int n)
{
- struct ppod_region *p;
- KASSERT(pr->used > 0, ("%s: nonsense free (%d)", __func__, pr->used));
+ MPASS(n > 0);
- mtx_lock(&td->ppod_lock);
- p = TAILQ_PREV(pr, ppod_head, link);
- if (p != NULL)
- p->free += pr->used + pr->free;
- else
- td->nppods_free_head += pr->used + pr->free;
- td->nppods_free += pr->used;
- KASSERT(td->nppods_free <= td->nppods,
- ("%s: nppods_free (%d) > nppods (%d). %d freed this time.",
- __func__, td->nppods_free, td->nppods, pr->used));
- TAILQ_REMOVE(&td->ppods, pr, link);
- mtx_unlock(&td->ppod_lock);
+ vmem_free(td->ppod_arena, (vmem_addr_t)ppod_addr, PPOD_SZ(n));
}
static inline int
@@ -187,7 +139,7 @@ free_ddp_buffer(struct tom_data *td, struct ddp_buffer *db)
free(db->pages, M_CXGBE);
if (db->nppods > 0)
- free_ppods(td, &db->ppod_region);
+ free_ppods(td, db->ppod_addr, db->nppods);
free(db, M_CXGBE);
}
@@ -702,6 +654,7 @@ alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
break;
}
have_pgsz:
+ MPASS(idx <= M_PPOD_PGSZ);
db = malloc(sizeof(*db), M_CXGBE, M_NOWAIT);
if (db == NULL) {
@@ -710,16 +663,13 @@ have_pgsz:
}
nppods = pages_to_nppods(npages, t4_ddp_pgsz[idx]);
- ppod = alloc_ppods(td, nppods, &db->ppod_region);
- if (ppod < 0) {
+ if (alloc_ppods(td, nppods, &db->ppod_addr) != 0) {
free(db, M_CXGBE);
CTR4(KTR_CXGBE, "%s: no pods, nppods %d, resid %d, pgsz %d",
__func__, nppods, len, t4_ddp_pgsz[idx]);
return (NULL);
}
-
- KASSERT(idx <= M_PPOD_PGSZ && ppod <= M_PPOD_TAG,
- ("%s: DDP pgsz_idx = %d, ppod = %d", __func__, idx, ppod));
+ ppod = (db->ppod_addr - td->ppod_start) / PPOD_SIZE;
db->tag = V_PPOD_PGSZ(idx) | V_PPOD_TAG(ppod);
db->nppods = nppods;
@@ -745,7 +695,8 @@ write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
struct ulp_mem_io *ulpmc;
struct ulptx_idata *ulpsc;
struct pagepod *ppod;
- int i, j, k, n, chunk, len, ddp_pgsz, idx, ppod_addr;
+ int i, j, k, n, chunk, len, ddp_pgsz, idx;
+ u_int ppod_addr;
uint32_t cmd;
cmd = htobe32(V_ULPTX_CMD(ULP_TX_MEM_WRITE));
@@ -754,7 +705,7 @@ write_page_pods(struct adapter *sc, struct toepcb *toep, struct ddp_buffer *db)
else
cmd |= htobe32(F_T5_ULP_MEMIO_IMM);
ddp_pgsz = t4_ddp_pgsz[G_PPOD_PGSZ(db->tag)];
- ppod_addr = sc->vres.ddp.start + G_PPOD_TAG(db->tag) * PPOD_SIZE;
+ ppod_addr = db->ppod_addr;
for (i = 0; i < db->nppods; ppod_addr += chunk) {
/* How many page pods are we writing in this cycle */
@@ -986,13 +937,10 @@ no_ddp:
void
t4_init_ddp(struct adapter *sc, struct tom_data *td)
{
- int nppods = sc->vres.ddp.size / PPOD_SIZE;
- td->nppods = nppods;
- td->nppods_free = nppods;
- td->nppods_free_head = nppods;
- TAILQ_INIT(&td->ppods);
- mtx_init(&td->ppod_lock, "page pods", NULL, MTX_DEF);
+ td->ppod_start = sc->vres.ddp.start;
+ td->ppod_arena = vmem_create("DDP page pods", sc->vres.ddp.start,
+ sc->vres.ddp.size, 1, 32, M_FIRSTFIT | M_NOWAIT);
t4_register_cpl_handler(sc, CPL_RX_DATA_DDP, do_rx_data_ddp);
t4_register_cpl_handler(sc, CPL_RX_DDP_COMPLETE, do_rx_ddp_complete);
@@ -1002,12 +950,10 @@ void
t4_uninit_ddp(struct adapter *sc __unused, struct tom_data *td)
{
- KASSERT(td->nppods == td->nppods_free,
- ("%s: page pods still in use, nppods = %d, free = %d",
- __func__, td->nppods, td->nppods_free));
-
- if (mtx_initialized(&td->ppod_lock))
- mtx_destroy(&td->ppod_lock);
+ if (td->ppod_arena != NULL) {
+ vmem_destroy(td->ppod_arena);
+ td->ppod_arena = NULL;
+ }
}
#define VNET_SO_ASSERT(so) \
diff --git a/sys/dev/cxgbe/tom/t4_tom.h b/sys/dev/cxgbe/tom/t4_tom.h
index 90532f5..67306cb 100644
--- a/sys/dev/cxgbe/tom/t4_tom.h
+++ b/sys/dev/cxgbe/tom/t4_tom.h
@@ -30,6 +30,7 @@
#ifndef __T4_TOM_H__
#define __T4_TOM_H__
+#include <sys/vmem.h>
#define LISTEN_HASH_SIZE 32
@@ -80,18 +81,12 @@ struct ofld_tx_sdesc {
uint8_t tx_credits; /* firmware tx credits (unit is 16B) */
};
-struct ppod_region {
- TAILQ_ENTRY(ppod_region) link;
- int used; /* # of pods used by this region */
- int free; /* # of contiguous pods free right after this region */
-};
-
struct ddp_buffer {
uint32_t tag; /* includes color, page pod addr, and DDP page size */
+ u_int ppod_addr;
int nppods;
int offset;
int len;
- struct ppod_region ppod_region;
int npages;
vm_page_t *pages;
};
@@ -179,8 +174,6 @@ struct listen_ctx {
TAILQ_HEAD(, synq_entry) synq;
};
-TAILQ_HEAD(ppod_head, ppod_region);
-
struct clip_entry {
TAILQ_ENTRY(clip_entry) link;
struct in6_addr lip; /* local IPv6 address */
@@ -200,11 +193,8 @@ struct tom_data {
u_long listen_mask;
int lctx_count; /* # of lctx in the hash table */
- struct mtx ppod_lock;
- int nppods;
- int nppods_free; /* # of available ppods */
- int nppods_free_head; /* # of available ppods at the begining */
- struct ppod_head ppods;
+ u_int ppod_start;
+ vmem_t *ppod_arena;
struct mtx clip_table_lock;
struct clip_head clip_table;
OpenPOWER on IntegriCloud