version 1.76.4.1, 2002/07/15 10:36:39 |
version 1.87, 2003/04/09 18:22:13 |
Line 94 struct pool_item_header { |
|
Line 94 struct pool_item_header { |
|
TAILQ_HEAD(,pool_item) ph_itemlist; /* chunk list for this page */ |
TAILQ_HEAD(,pool_item) ph_itemlist; /* chunk list for this page */ |
LIST_ENTRY(pool_item_header) |
LIST_ENTRY(pool_item_header) |
ph_hashlist; /* Off-page page headers */ |
ph_hashlist; /* Off-page page headers */ |
int ph_nmissing; /* # of chunks in use */ |
unsigned int ph_nmissing; /* # of chunks in use */ |
caddr_t ph_page; /* this page's address */ |
caddr_t ph_page; /* this page's address */ |
struct timeval ph_time; /* last referenced */ |
struct timeval ph_time; /* last referenced */ |
}; |
}; |
Line 102 TAILQ_HEAD(pool_pagelist,pool_item_heade |
|
Line 102 TAILQ_HEAD(pool_pagelist,pool_item_heade |
|
|
|
struct pool_item { |
struct pool_item { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
int pi_magic; |
u_int pi_magic; |
#endif |
#endif |
#define PI_MAGIC 0xdeadbeef |
#define PI_MAGIC 0xdeadbeefU |
/* Other entries use only this list entry */ |
/* Other entries use only this list entry */ |
TAILQ_ENTRY(pool_item) pi_list; |
TAILQ_ENTRY(pool_item) pi_list; |
}; |
}; |
Line 169 struct pool_log { |
|
Line 169 struct pool_log { |
|
void *pl_addr; |
void *pl_addr; |
}; |
}; |
|
|
|
#ifdef POOL_DIAGNOSTIC |
/* Number of entries in pool log buffers */ |
/* Number of entries in pool log buffers */ |
#ifndef POOL_LOGSIZE |
#ifndef POOL_LOGSIZE |
#define POOL_LOGSIZE 10 |
#define POOL_LOGSIZE 10 |
Line 176 struct pool_log { |
|
Line 177 struct pool_log { |
|
|
|
int pool_logsize = POOL_LOGSIZE; |
int pool_logsize = POOL_LOGSIZE; |
|
|
#ifdef POOL_DIAGNOSTIC |
|
static __inline void |
static __inline void |
pr_log(struct pool *pp, void *v, int action, const char *file, long line) |
pr_log(struct pool *pp, void *v, int action, const char *file, long line) |
{ |
{ |
Line 329 pr_rmpage(struct pool *pp, struct pool_i |
|
Line 329 pr_rmpage(struct pool *pp, struct pool_i |
|
pool_allocator_free(pp, ph->ph_page); |
pool_allocator_free(pp, ph->ph_page); |
if ((pp->pr_roflags & PR_PHINPAGE) == 0) { |
if ((pp->pr_roflags & PR_PHINPAGE) == 0) { |
LIST_REMOVE(ph, ph_hashlist); |
LIST_REMOVE(ph, ph_hashlist); |
s = splhigh(); |
s = splvm(); |
pool_put(&phpool, ph); |
pool_put(&phpool, ph); |
splx(s); |
splx(s); |
} |
} |
Line 415 pool_init(struct pool *pp, size_t size, |
|
Line 415 pool_init(struct pool *pp, size_t size, |
|
if (size < sizeof(struct pool_item)) |
if (size < sizeof(struct pool_item)) |
size = sizeof(struct pool_item); |
size = sizeof(struct pool_item); |
|
|
size = ALIGN(size); |
size = roundup(size, align); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (size > palloc->pa_pagesz) |
if (size > palloc->pa_pagesz) |
panic("pool_init: pool item size (%lu) too large", |
panic("pool_init: pool item size (%lu) too large", |
Line 564 pool_destroy(struct pool *pp) |
|
Line 564 pool_destroy(struct pool *pp) |
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (pp->pr_nout != 0) { |
if (pp->pr_nout != 0) { |
pr_printlog(pp, NULL, printf); |
pr_printlog(pp, NULL, printf); |
panic("pool_destroy: pool busy: still out: %u\n", |
panic("pool_destroy: pool busy: still out: %u", |
pp->pr_nout); |
pp->pr_nout); |
} |
} |
#endif |
#endif |
Line 611 pool_alloc_item_header(struct pool *pp, |
|
Line 611 pool_alloc_item_header(struct pool *pp, |
|
if ((pp->pr_roflags & PR_PHINPAGE) != 0) |
if ((pp->pr_roflags & PR_PHINPAGE) != 0) |
ph = (struct pool_item_header *) (storage + pp->pr_phoffset); |
ph = (struct pool_item_header *) (storage + pp->pr_phoffset); |
else { |
else { |
s = splhigh(); |
s = splvm(); |
ph = pool_get(&phpool, flags); |
ph = pool_get(&phpool, flags); |
splx(s); |
splx(s); |
} |
} |
Line 634 pool_get(struct pool *pp, int flags) |
|
Line 634 pool_get(struct pool *pp, int flags) |
|
void *v; |
void *v; |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (__predict_false(curproc == NULL && doing_shutdown == 0 && |
if (__predict_false(curlwp == NULL && doing_shutdown == 0 && |
(flags & PR_WAITOK) != 0)) |
(flags & PR_WAITOK) != 0)) |
panic("pool_get: %s: must have NOWAIT", pp->pr_wchan); |
panic("pool_get: %s: must have NOWAIT", pp->pr_wchan); |
|
|
Line 715 pool_get(struct pool *pp, int flags) |
|
Line 715 pool_get(struct pool *pp, int flags) |
|
simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
printf("pool_get: %s: curpage NULL, nitems %u\n", |
printf("pool_get: %s: curpage NULL, nitems %u\n", |
pp->pr_wchan, pp->pr_nitems); |
pp->pr_wchan, pp->pr_nitems); |
panic("pool_get: nitems inconsistent\n"); |
panic("pool_get: nitems inconsistent"); |
} |
} |
#endif |
#endif |
|
|
Line 785 pool_get(struct pool *pp, int flags) |
|
Line 785 pool_get(struct pool *pp, int flags) |
|
simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
printf("pool_get: %s: items on itemlist, nitems %u\n", |
printf("pool_get: %s: items on itemlist, nitems %u\n", |
pp->pr_wchan, pp->pr_nitems); |
pp->pr_wchan, pp->pr_nitems); |
panic("pool_get: nitems inconsistent\n"); |
panic("pool_get: nitems inconsistent"); |
} |
} |
#endif |
#endif |
|
|
Line 916 pool_do_put(struct pool *pp, void *v) |
|
Line 916 pool_do_put(struct pool *pp, void *v) |
|
#endif |
#endif |
|
|
TAILQ_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list); |
TAILQ_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list); |
|
KDASSERT(ph->ph_nmissing != 0); |
ph->ph_nmissing--; |
ph->ph_nmissing--; |
pp->pr_nput++; |
pp->pr_nput++; |
pp->pr_nitems++; |
pp->pr_nitems++; |
Line 1036 pool_put(struct pool *pp, void *v) |
|
Line 1037 pool_put(struct pool *pp, void *v) |
|
int |
int |
pool_prime(struct pool *pp, int n) |
pool_prime(struct pool *pp, int n) |
{ |
{ |
struct pool_item_header *ph; |
struct pool_item_header *ph = NULL; |
caddr_t cp; |
caddr_t cp; |
int newpages; |
int newpages; |
|
|
Line 1125 pool_prime_page(struct pool *pp, caddr_t |
|
Line 1126 pool_prime_page(struct pool *pp, caddr_t |
|
while (n--) { |
while (n--) { |
pi = (struct pool_item *)cp; |
pi = (struct pool_item *)cp; |
|
|
|
KASSERT(((((vaddr_t)pi) + ioff) & (align - 1)) == 0); |
|
|
/* Insert on page list */ |
/* Insert on page list */ |
TAILQ_INSERT_TAIL(&ph->ph_itemlist, pi, pi_list); |
TAILQ_INSERT_TAIL(&ph->ph_itemlist, pi, pi_list); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
Line 1155 pool_prime_page(struct pool *pp, caddr_t |
|
Line 1158 pool_prime_page(struct pool *pp, caddr_t |
|
static int |
static int |
pool_catchup(struct pool *pp) |
pool_catchup(struct pool *pp) |
{ |
{ |
struct pool_item_header *ph; |
struct pool_item_header *ph = NULL; |
caddr_t cp; |
caddr_t cp; |
int error = 0; |
int error = 0; |
|
|
Line 1319 pool_reclaim(struct pool *pp) |
|
Line 1322 pool_reclaim(struct pool *pp) |
|
continue; |
continue; |
} |
} |
LIST_REMOVE(ph, ph_hashlist); |
LIST_REMOVE(ph, ph_hashlist); |
s = splhigh(); |
s = splvm(); |
pool_put(&phpool, ph); |
pool_put(&phpool, ph); |
splx(s); |
splx(s); |
} |
} |
Line 1422 pool_print1(struct pool *pp, const char |
|
Line 1425 pool_print1(struct pool *pp, const char |
|
print_pagelist = 1; |
print_pagelist = 1; |
if (c == 'c') |
if (c == 'c') |
print_cache = 1; |
print_cache = 1; |
modif++; |
|
} |
} |
|
|
(*pr)("POOL %s: size %u, align %u, ioff %u, roflags 0x%08x\n", |
(*pr)("POOL %s: size %u, align %u, ioff %u, roflags 0x%08x\n", |
Line 1486 pool_print1(struct pool *pp, const char |
|
Line 1488 pool_print1(struct pool *pp, const char |
|
pc->pc_hits, pc->pc_misses, pc->pc_ngroups, pc->pc_nitems); |
pc->pc_hits, pc->pc_misses, pc->pc_ngroups, pc->pc_nitems); |
TAILQ_FOREACH(pcg, &pc->pc_grouplist, pcg_list) { |
TAILQ_FOREACH(pcg, &pc->pc_grouplist, pcg_list) { |
(*pr)("\t\tgroup %p: avail %d\n", pcg, pcg->pcg_avail); |
(*pr)("\t\tgroup %p: avail %d\n", pcg, pcg->pcg_avail); |
for (i = 0; i < PCG_NOBJECTS; i++) |
for (i = 0; i < PCG_NOBJECTS; i++) { |
(*pr)("\t\t\t%p\n", pcg->pcg_objects[i]); |
if (pcg->pcg_objects[i].pcgo_pa != |
|
POOL_PADDR_INVALID) { |
|
(*pr)("\t\t\t%p, 0x%llx\n", |
|
pcg->pcg_objects[i].pcgo_va, |
|
(unsigned long long) |
|
pcg->pcg_objects[i].pcgo_pa); |
|
} else { |
|
(*pr)("\t\t\t%p\n", |
|
pcg->pcg_objects[i].pcgo_va); |
|
} |
|
} |
} |
} |
} |
} |
|
|
Line 1616 pool_cache_destroy(struct pool_cache *pc |
|
Line 1628 pool_cache_destroy(struct pool_cache *pc |
|
} |
} |
|
|
static __inline void * |
static __inline void * |
pcg_get(struct pool_cache_group *pcg) |
pcg_get(struct pool_cache_group *pcg, paddr_t *pap) |
{ |
{ |
void *object; |
void *object; |
u_int idx; |
u_int idx; |
Line 1625 pcg_get(struct pool_cache_group *pcg) |
|
Line 1637 pcg_get(struct pool_cache_group *pcg) |
|
KASSERT(pcg->pcg_avail != 0); |
KASSERT(pcg->pcg_avail != 0); |
idx = --pcg->pcg_avail; |
idx = --pcg->pcg_avail; |
|
|
KASSERT(pcg->pcg_objects[idx] != NULL); |
KASSERT(pcg->pcg_objects[idx].pcgo_va != NULL); |
object = pcg->pcg_objects[idx]; |
object = pcg->pcg_objects[idx].pcgo_va; |
pcg->pcg_objects[idx] = NULL; |
if (pap != NULL) |
|
*pap = pcg->pcg_objects[idx].pcgo_pa; |
|
pcg->pcg_objects[idx].pcgo_va = NULL; |
|
|
return (object); |
return (object); |
} |
} |
|
|
static __inline void |
static __inline void |
pcg_put(struct pool_cache_group *pcg, void *object) |
pcg_put(struct pool_cache_group *pcg, void *object, paddr_t pa) |
{ |
{ |
u_int idx; |
u_int idx; |
|
|
KASSERT(pcg->pcg_avail < PCG_NOBJECTS); |
KASSERT(pcg->pcg_avail < PCG_NOBJECTS); |
idx = pcg->pcg_avail++; |
idx = pcg->pcg_avail++; |
|
|
KASSERT(pcg->pcg_objects[idx] == NULL); |
KASSERT(pcg->pcg_objects[idx].pcgo_va == NULL); |
pcg->pcg_objects[idx] = object; |
pcg->pcg_objects[idx].pcgo_va = object; |
|
pcg->pcg_objects[idx].pcgo_pa = pa; |
} |
} |
|
|
/* |
/* |
* pool_cache_get: |
* pool_cache_get{,_paddr}: |
* |
* |
* Get an object from a pool cache. |
* Get an object from a pool cache (optionally returning |
|
* the physical address of the object). |
*/ |
*/ |
void * |
void * |
pool_cache_get(struct pool_cache *pc, int flags) |
pool_cache_get_paddr(struct pool_cache *pc, int flags, paddr_t *pap) |
{ |
{ |
struct pool_cache_group *pcg; |
struct pool_cache_group *pcg; |
void *object; |
void *object; |
Line 1685 pool_cache_get(struct pool_cache *pc, in |
|
Line 1701 pool_cache_get(struct pool_cache *pc, in |
|
return (NULL); |
return (NULL); |
} |
} |
} |
} |
|
if (object != NULL && pap != NULL) { |
|
#ifdef POOL_VTOPHYS |
|
*pap = POOL_VTOPHYS(object); |
|
#else |
|
*pap = POOL_PADDR_INVALID; |
|
#endif |
|
} |
return (object); |
return (object); |
} |
} |
|
|
have_group: |
have_group: |
pc->pc_hits++; |
pc->pc_hits++; |
pc->pc_nitems--; |
pc->pc_nitems--; |
object = pcg_get(pcg); |
object = pcg_get(pcg, pap); |
|
|
if (pcg->pcg_avail == 0) |
if (pcg->pcg_avail == 0) |
pc->pc_allocfrom = NULL; |
pc->pc_allocfrom = NULL; |
Line 1702 pool_cache_get(struct pool_cache *pc, in |
|
Line 1725 pool_cache_get(struct pool_cache *pc, in |
|
} |
} |
|
|
/* |
/* |
* pool_cache_put: |
* pool_cache_put{,_paddr}: |
* |
* |
* Put an object back to the pool cache. |
* Put an object back to the pool cache (optionally caching the |
|
* physical address of the object). |
*/ |
*/ |
void |
void |
pool_cache_put(struct pool_cache *pc, void *object) |
pool_cache_put_paddr(struct pool_cache *pc, void *object, paddr_t pa) |
{ |
{ |
struct pool_cache_group *pcg; |
struct pool_cache_group *pcg; |
int s; |
int s; |
Line 1750 pool_cache_put(struct pool_cache *pc, vo |
|
Line 1774 pool_cache_put(struct pool_cache *pc, vo |
|
|
|
have_group: |
have_group: |
pc->pc_nitems++; |
pc->pc_nitems++; |
pcg_put(pcg, object); |
pcg_put(pcg, object, pa); |
|
|
if (pcg->pcg_avail == PCG_NOBJECTS) |
if (pcg->pcg_avail == PCG_NOBJECTS) |
pc->pc_freeto = NULL; |
pc->pc_freeto = NULL; |
Line 1792 pool_cache_do_invalidate(struct pool_cac |
|
Line 1816 pool_cache_do_invalidate(struct pool_cac |
|
npcg = TAILQ_NEXT(pcg, pcg_list); |
npcg = TAILQ_NEXT(pcg, pcg_list); |
while (pcg->pcg_avail != 0) { |
while (pcg->pcg_avail != 0) { |
pc->pc_nitems--; |
pc->pc_nitems--; |
object = pcg_get(pcg); |
object = pcg_get(pcg, NULL); |
if (pcg->pcg_avail == 0 && pc->pc_allocfrom == pcg) |
if (pcg->pcg_avail == 0 && pc->pc_allocfrom == pcg) |
pc->pc_allocfrom = NULL; |
pc->pc_allocfrom = NULL; |
if (pc->pc_dtor != NULL) |
if (pc->pc_dtor != NULL) |