mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
cxgbe/tom: use vmem(9) as the DDP page pod allocator.
MFC after: 1 month
This commit is contained in:
parent
008015d2f4
commit
f8c479085f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276729
@ -98,74 +98,24 @@ t4_dump_tcb(struct adapter *sc, int tid)
|
|||||||
|
|
||||||
#define MAX_DDP_BUFFER_SIZE (M_TCB_RX_DDP_BUF0_LEN)
|
#define MAX_DDP_BUFFER_SIZE (M_TCB_RX_DDP_BUF0_LEN)
|
||||||
static int
|
static int
|
||||||
alloc_ppods(struct tom_data *td, int n, struct ppod_region *pr)
|
alloc_ppods(struct tom_data *td, int n)
|
||||||
{
|
{
|
||||||
int ppod;
|
vmem_addr_t ppod;
|
||||||
|
|
||||||
KASSERT(n > 0, ("%s: nonsense allocation (%d)", __func__, n));
|
MPASS(n > 0);
|
||||||
|
|
||||||
mtx_lock(&td->ppod_lock);
|
if (vmem_alloc(td->ppod_arena, n, M_NOWAIT | M_FIRSTFIT, &ppod) != 0)
|
||||||
if (n > td->nppods_free) {
|
|
||||||
mtx_unlock(&td->ppod_lock);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
return ((int)ppod);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_ppods(struct tom_data *td, struct ppod_region *pr)
|
free_ppods(struct tom_data *td, int ppod, 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);
|
vmem_free(td->ppod_arena, ppod, n);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@ -187,7 +137,7 @@ free_ddp_buffer(struct tom_data *td, struct ddp_buffer *db)
|
|||||||
free(db->pages, M_CXGBE);
|
free(db->pages, M_CXGBE);
|
||||||
|
|
||||||
if (db->nppods > 0)
|
if (db->nppods > 0)
|
||||||
free_ppods(td, &db->ppod_region);
|
free_ppods(td, G_PPOD_TAG(db->tag), db->nppods);
|
||||||
|
|
||||||
free(db, M_CXGBE);
|
free(db, M_CXGBE);
|
||||||
}
|
}
|
||||||
@ -710,7 +660,7 @@ alloc_ddp_buffer(struct tom_data *td, vm_page_t *pages, int npages, int offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nppods = pages_to_nppods(npages, t4_ddp_pgsz[idx]);
|
nppods = pages_to_nppods(npages, t4_ddp_pgsz[idx]);
|
||||||
ppod = alloc_ppods(td, nppods, &db->ppod_region);
|
ppod = alloc_ppods(td, nppods);
|
||||||
if (ppod < 0) {
|
if (ppod < 0) {
|
||||||
free(db, M_CXGBE);
|
free(db, M_CXGBE);
|
||||||
CTR4(KTR_CXGBE, "%s: no pods, nppods %d, resid %d, pgsz %d",
|
CTR4(KTR_CXGBE, "%s: no pods, nppods %d, resid %d, pgsz %d",
|
||||||
@ -989,11 +939,8 @@ t4_init_ddp(struct adapter *sc, struct tom_data *td)
|
|||||||
{
|
{
|
||||||
int nppods = sc->vres.ddp.size / PPOD_SIZE;
|
int nppods = sc->vres.ddp.size / PPOD_SIZE;
|
||||||
|
|
||||||
td->nppods = nppods;
|
td->ppod_arena = vmem_create("DDP page pods", 0, nppods, 1, 32,
|
||||||
td->nppods_free = nppods;
|
M_FIRSTFIT | M_NOWAIT);
|
||||||
td->nppods_free_head = nppods;
|
|
||||||
TAILQ_INIT(&td->ppods);
|
|
||||||
mtx_init(&td->ppod_lock, "page pods", NULL, MTX_DEF);
|
|
||||||
|
|
||||||
t4_register_cpl_handler(sc, CPL_RX_DATA_DDP, do_rx_data_ddp);
|
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);
|
t4_register_cpl_handler(sc, CPL_RX_DDP_COMPLETE, do_rx_ddp_complete);
|
||||||
@ -1003,12 +950,10 @@ void
|
|||||||
t4_uninit_ddp(struct adapter *sc __unused, struct tom_data *td)
|
t4_uninit_ddp(struct adapter *sc __unused, struct tom_data *td)
|
||||||
{
|
{
|
||||||
|
|
||||||
KASSERT(td->nppods == td->nppods_free,
|
if (td->ppod_arena != NULL) {
|
||||||
("%s: page pods still in use, nppods = %d, free = %d",
|
vmem_destroy(td->ppod_arena);
|
||||||
__func__, td->nppods, td->nppods_free));
|
td->ppod_arena = NULL;
|
||||||
|
}
|
||||||
if (mtx_initialized(&td->ppod_lock))
|
|
||||||
mtx_destroy(&td->ppod_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VNET_SO_ASSERT(so) \
|
#define VNET_SO_ASSERT(so) \
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#ifndef __T4_TOM_H__
|
#ifndef __T4_TOM_H__
|
||||||
#define __T4_TOM_H__
|
#define __T4_TOM_H__
|
||||||
|
#include <sys/vmem.h>
|
||||||
|
|
||||||
#define LISTEN_HASH_SIZE 32
|
#define LISTEN_HASH_SIZE 32
|
||||||
|
|
||||||
@ -80,18 +81,11 @@ struct ofld_tx_sdesc {
|
|||||||
uint8_t tx_credits; /* firmware tx credits (unit is 16B) */
|
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 {
|
struct ddp_buffer {
|
||||||
uint32_t tag; /* includes color, page pod addr, and DDP page size */
|
uint32_t tag; /* includes color, page pod addr, and DDP page size */
|
||||||
int nppods;
|
int nppods;
|
||||||
int offset;
|
int offset;
|
||||||
int len;
|
int len;
|
||||||
struct ppod_region ppod_region;
|
|
||||||
int npages;
|
int npages;
|
||||||
vm_page_t *pages;
|
vm_page_t *pages;
|
||||||
};
|
};
|
||||||
@ -179,8 +173,6 @@ struct listen_ctx {
|
|||||||
TAILQ_HEAD(, synq_entry) synq;
|
TAILQ_HEAD(, synq_entry) synq;
|
||||||
};
|
};
|
||||||
|
|
||||||
TAILQ_HEAD(ppod_head, ppod_region);
|
|
||||||
|
|
||||||
struct clip_entry {
|
struct clip_entry {
|
||||||
TAILQ_ENTRY(clip_entry) link;
|
TAILQ_ENTRY(clip_entry) link;
|
||||||
struct in6_addr lip; /* local IPv6 address */
|
struct in6_addr lip; /* local IPv6 address */
|
||||||
@ -200,11 +192,7 @@ struct tom_data {
|
|||||||
u_long listen_mask;
|
u_long listen_mask;
|
||||||
int lctx_count; /* # of lctx in the hash table */
|
int lctx_count; /* # of lctx in the hash table */
|
||||||
|
|
||||||
struct mtx ppod_lock;
|
vmem_t *ppod_arena;
|
||||||
int nppods;
|
|
||||||
int nppods_free; /* # of available ppods */
|
|
||||||
int nppods_free_head; /* # of available ppods at the begining */
|
|
||||||
struct ppod_head ppods;
|
|
||||||
|
|
||||||
struct mtx clip_table_lock;
|
struct mtx clip_table_lock;
|
||||||
struct clip_head clip_table;
|
struct clip_head clip_table;
|
||||||
|
Loading…
Reference in New Issue
Block a user