version 1.93, 2004/03/08 22:48:09 |
version 1.99.4.1, 2005/01/25 12:59:35 |
Line 73 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 73 __KERNEL_RCSID(0, "$NetBSD$"); |
|
TAILQ_HEAD(,pool) pool_head = TAILQ_HEAD_INITIALIZER(pool_head); |
TAILQ_HEAD(,pool) pool_head = TAILQ_HEAD_INITIALIZER(pool_head); |
|
|
/* Private pool for page header structures */ |
/* Private pool for page header structures */ |
static struct pool phpool; |
#define PHPOOL_MAX 8 |
|
static struct pool phpool[PHPOOL_MAX]; |
|
#define PHPOOL_FREELIST_NELEM(idx) (((idx) == 0) ? 0 : (1 << (idx))) |
|
|
#ifdef POOL_SUBPAGE |
#ifdef POOL_SUBPAGE |
/* Pool of subpages for use by normal pools. */ |
/* Pool of subpages for use by normal pools. */ |
static struct pool psppool; |
static struct pool psppool; |
#endif |
#endif |
|
|
|
static void *pool_page_alloc_meta(struct pool *, int); |
|
static void pool_page_free_meta(struct pool *, void *); |
|
|
|
/* allocator for pool metadata */ |
|
static struct pool_allocator pool_allocator_meta = { |
|
pool_page_alloc_meta, pool_page_free_meta |
|
}; |
|
|
/* # of seconds to retain page after last use */ |
/* # of seconds to retain page after last use */ |
int pool_inactive_time = 10; |
int pool_inactive_time = 10; |
|
|
Line 89 static struct pool *drainpp; |
|
Line 99 static struct pool *drainpp; |
|
/* This spin lock protects both pool_head and drainpp. */ |
/* This spin lock protects both pool_head and drainpp. */ |
struct simplelock pool_head_slock = SIMPLELOCK_INITIALIZER; |
struct simplelock pool_head_slock = SIMPLELOCK_INITIALIZER; |
|
|
|
typedef uint8_t pool_item_freelist_t; |
|
|
struct pool_item_header { |
struct pool_item_header { |
/* Page headers */ |
/* Page headers */ |
LIST_ENTRY(pool_item_header) |
LIST_ENTRY(pool_item_header) |
ph_pagelist; /* pool page list */ |
ph_pagelist; /* pool page list */ |
TAILQ_HEAD(,pool_item) ph_itemlist; /* chunk list for this page */ |
|
SPLAY_ENTRY(pool_item_header) |
SPLAY_ENTRY(pool_item_header) |
ph_node; /* Off-page page headers */ |
ph_node; /* Off-page page headers */ |
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 */ |
|
union { |
|
/* !PR_NOTOUCH */ |
|
struct { |
|
TAILQ_HEAD(, pool_item) |
|
phu_itemlist; /* chunk list for this page */ |
|
} phu_normal; |
|
/* PR_NOTOUCH */ |
|
struct { |
|
uint16_t |
|
phu_off; /* start offset in page */ |
|
pool_item_freelist_t |
|
phu_firstfree; /* first free item */ |
|
/* |
|
* XXX it might be better to use |
|
* a simple bitmap and ffs(3) |
|
*/ |
|
} phu_notouch; |
|
} ph_u; |
|
uint16_t ph_nmissing; /* # of chunks in use */ |
}; |
}; |
|
#define ph_itemlist ph_u.phu_normal.phu_itemlist |
|
#define ph_off ph_u.phu_notouch.phu_off |
|
#define ph_firstfree ph_u.phu_notouch.phu_firstfree |
|
|
struct pool_item { |
struct pool_item { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
Line 152 static void pool_update_curpage(struct p |
|
Line 184 static void pool_update_curpage(struct p |
|
void *pool_allocator_alloc(struct pool *, int); |
void *pool_allocator_alloc(struct pool *, int); |
void pool_allocator_free(struct pool *, void *); |
void pool_allocator_free(struct pool *, void *); |
|
|
static void pool_print_pagelist(struct pool_pagelist *, |
static void pool_print_pagelist(struct pool *, struct pool_pagelist *, |
void (*)(const char *, ...)); |
void (*)(const char *, ...)); |
static void pool_print1(struct pool *, const char *, |
static void pool_print1(struct pool *, const char *, |
void (*)(const char *, ...)); |
void (*)(const char *, ...)); |
Line 279 pr_enter_check(struct pool *pp, void (*p |
|
Line 311 pr_enter_check(struct pool *pp, void (*p |
|
#endif /* POOL_DIAGNOSTIC */ |
#endif /* POOL_DIAGNOSTIC */ |
|
|
static __inline int |
static __inline int |
|
pr_item_notouch_index(const struct pool *pp, const struct pool_item_header *ph, |
|
const void *v) |
|
{ |
|
const char *cp = v; |
|
int idx; |
|
|
|
KASSERT(pp->pr_roflags & PR_NOTOUCH); |
|
idx = (cp - ph->ph_page - ph->ph_off) / pp->pr_size; |
|
KASSERT(idx < pp->pr_itemsperpage); |
|
return idx; |
|
} |
|
|
|
#define PR_FREELIST_ALIGN(p) \ |
|
roundup((uintptr_t)(p), sizeof(pool_item_freelist_t)) |
|
#define PR_FREELIST(ph) ((pool_item_freelist_t *)PR_FREELIST_ALIGN((ph) + 1)) |
|
#define PR_INDEX_USED ((pool_item_freelist_t)-1) |
|
#define PR_INDEX_EOL ((pool_item_freelist_t)-2) |
|
|
|
static __inline void |
|
pr_item_notouch_put(const struct pool *pp, struct pool_item_header *ph, |
|
void *obj) |
|
{ |
|
int idx = pr_item_notouch_index(pp, ph, obj); |
|
pool_item_freelist_t *freelist = PR_FREELIST(ph); |
|
|
|
KASSERT(freelist[idx] == PR_INDEX_USED); |
|
freelist[idx] = ph->ph_firstfree; |
|
ph->ph_firstfree = idx; |
|
} |
|
|
|
static __inline void * |
|
pr_item_notouch_get(const struct pool *pp, struct pool_item_header *ph) |
|
{ |
|
int idx = ph->ph_firstfree; |
|
pool_item_freelist_t *freelist = PR_FREELIST(ph); |
|
|
|
KASSERT(freelist[idx] != PR_INDEX_USED); |
|
ph->ph_firstfree = freelist[idx]; |
|
freelist[idx] = PR_INDEX_USED; |
|
|
|
return ph->ph_page + ph->ph_off + idx * pp->pr_size; |
|
} |
|
|
|
static __inline int |
phtree_compare(struct pool_item_header *a, struct pool_item_header *b) |
phtree_compare(struct pool_item_header *a, struct pool_item_header *b) |
{ |
{ |
if (a->ph_page < b->ph_page) |
if (a->ph_page < b->ph_page) |
Line 346 pr_rmpage(struct pool *pp, struct pool_i |
|
Line 422 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) { |
s = splvm(); |
s = splvm(); |
pool_put(&phpool, ph); |
pool_put(pp->pr_phpool, ph); |
splx(s); |
splx(s); |
} |
} |
} |
} |
Line 357 pr_rmpage(struct pool *pp, struct pool_i |
|
Line 433 pr_rmpage(struct pool *pp, struct pool_i |
|
} |
} |
|
|
/* |
/* |
|
* Initialize all the pools listed in the "pools" link set. |
|
*/ |
|
void |
|
link_pool_init(void) |
|
{ |
|
__link_set_decl(pools, struct link_pool_init); |
|
struct link_pool_init * const *pi; |
|
|
|
__link_set_foreach(pi, pools) |
|
pool_init((*pi)->pp, (*pi)->size, (*pi)->align, |
|
(*pi)->align_offset, (*pi)->flags, (*pi)->wchan, |
|
(*pi)->palloc); |
|
} |
|
|
|
/* |
* Initialize the given pool resource structure. |
* Initialize the given pool resource structure. |
* |
* |
* We export this routine to allow other kernel parts to declare |
* We export this routine to allow other kernel parts to declare |
Line 370 pool_init(struct pool *pp, size_t size, |
|
Line 461 pool_init(struct pool *pp, size_t size, |
|
size_t trysize, phsize; |
size_t trysize, phsize; |
int s; |
int s; |
|
|
|
KASSERT((1UL << (CHAR_BIT * sizeof(pool_item_freelist_t))) - 2 >= |
|
PHPOOL_FREELIST_NELEM(PHPOOL_MAX - 1)); |
|
|
#ifdef POOL_DIAGNOSTIC |
#ifdef POOL_DIAGNOSTIC |
/* |
/* |
* Always log if POOL_DIAGNOSTIC is defined. |
* Always log if POOL_DIAGNOSTIC is defined. |
Line 475 pool_init(struct pool *pp, size_t size, |
|
Line 569 pool_init(struct pool *pp, size_t size, |
|
/* See the comment below about reserved bytes. */ |
/* See the comment below about reserved bytes. */ |
trysize = palloc->pa_pagesz - ((align - ioff) % align); |
trysize = palloc->pa_pagesz - ((align - ioff) % align); |
phsize = ALIGN(sizeof(struct pool_item_header)); |
phsize = ALIGN(sizeof(struct pool_item_header)); |
if (pp->pr_size < MIN(palloc->pa_pagesz / 16, phsize << 3) || |
if ((pp->pr_roflags & PR_NOTOUCH) == 0 && |
trysize / pp->pr_size == (trysize - phsize) / pp->pr_size) { |
(pp->pr_size < MIN(palloc->pa_pagesz / 16, phsize << 3) || |
|
trysize / pp->pr_size == (trysize - phsize) / pp->pr_size)) { |
/* Use the end of the page for the page header */ |
/* Use the end of the page for the page header */ |
pp->pr_roflags |= PR_PHINPAGE; |
pp->pr_roflags |= PR_PHINPAGE; |
pp->pr_phoffset = off = palloc->pa_pagesz - phsize; |
pp->pr_phoffset = off = palloc->pa_pagesz - phsize; |
Line 494 pool_init(struct pool *pp, size_t size, |
|
Line 589 pool_init(struct pool *pp, size_t size, |
|
*/ |
*/ |
pp->pr_itemsperpage = (off - ((align - ioff) % align)) / pp->pr_size; |
pp->pr_itemsperpage = (off - ((align - ioff) % align)) / pp->pr_size; |
KASSERT(pp->pr_itemsperpage != 0); |
KASSERT(pp->pr_itemsperpage != 0); |
|
if ((pp->pr_roflags & PR_NOTOUCH)) { |
|
int idx; |
|
|
|
for (idx = 0; pp->pr_itemsperpage > PHPOOL_FREELIST_NELEM(idx); |
|
idx++) { |
|
/* nothing */ |
|
} |
|
if (idx >= PHPOOL_MAX) { |
|
/* |
|
* if you see this panic, consider to tweak |
|
* PHPOOL_MAX and PHPOOL_FREELIST_NELEM. |
|
*/ |
|
panic("%s: too large itemsperpage(%d) for PR_NOTOUCH", |
|
pp->pr_wchan, pp->pr_itemsperpage); |
|
} |
|
pp->pr_phpool = &phpool[idx]; |
|
} else if ((pp->pr_roflags & PR_PHINPAGE) == 0) { |
|
pp->pr_phpool = &phpool[0]; |
|
} |
|
#if defined(DIAGNOSTIC) |
|
else { |
|
pp->pr_phpool = NULL; |
|
} |
|
#endif |
|
|
/* |
/* |
* Use the slack between the chunks and the page header |
* Use the slack between the chunks and the page header |
Line 532 pool_init(struct pool *pp, size_t size, |
|
Line 651 pool_init(struct pool *pp, size_t size, |
|
* haven't done so yet. |
* haven't done so yet. |
* XXX LOCKING. |
* XXX LOCKING. |
*/ |
*/ |
if (phpool.pr_size == 0) { |
if (phpool[0].pr_size == 0) { |
|
int idx; |
|
for (idx = 0; idx < PHPOOL_MAX; idx++) { |
|
static char phpool_names[PHPOOL_MAX][6+1+6+1]; |
|
int nelem; |
|
size_t sz; |
|
|
|
nelem = PHPOOL_FREELIST_NELEM(idx); |
|
snprintf(phpool_names[idx], sizeof(phpool_names[idx]), |
|
"phpool-%d", nelem); |
|
sz = sizeof(struct pool_item_header); |
|
if (nelem) { |
|
sz = PR_FREELIST_ALIGN(sz) |
|
+ nelem * sizeof(pool_item_freelist_t); |
|
} |
|
pool_init(&phpool[idx], sz, 0, 0, 0, |
|
phpool_names[idx], &pool_allocator_meta); |
|
} |
#ifdef POOL_SUBPAGE |
#ifdef POOL_SUBPAGE |
pool_init(&phpool, sizeof(struct pool_item_header), 0, 0, 0, |
|
"phpool", &pool_allocator_kmem); |
|
pool_init(&psppool, POOL_SUBPAGE, POOL_SUBPAGE, 0, |
pool_init(&psppool, POOL_SUBPAGE, POOL_SUBPAGE, 0, |
PR_RECURSIVE, "psppool", &pool_allocator_kmem); |
PR_RECURSIVE, "psppool", &pool_allocator_meta); |
#else |
|
pool_init(&phpool, sizeof(struct pool_item_header), 0, 0, |
|
0, "phpool", NULL); |
|
#endif |
#endif |
pool_init(&pcgpool, sizeof(struct pool_cache_group), 0, 0, |
pool_init(&pcgpool, sizeof(struct pool_cache_group), 0, 0, |
0, "pcgpool", NULL); |
0, "pcgpool", &pool_allocator_meta); |
} |
} |
|
|
/* Insert into the list of all pools. */ |
/* Insert into the list of all pools. */ |
Line 633 pool_alloc_item_header(struct pool *pp, |
|
Line 764 pool_alloc_item_header(struct pool *pp, |
|
ph = (struct pool_item_header *) (storage + pp->pr_phoffset); |
ph = (struct pool_item_header *) (storage + pp->pr_phoffset); |
else { |
else { |
s = splvm(); |
s = splvm(); |
ph = pool_get(&phpool, flags); |
ph = pool_get(pp->pr_phpool, flags); |
splx(s); |
splx(s); |
} |
} |
|
|
Line 655 pool_get(struct pool *pp, int flags) |
|
Line 786 pool_get(struct pool *pp, int flags) |
|
void *v; |
void *v; |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
|
if (__predict_false(pp->pr_itemsperpage == 0)) |
|
panic("pool_get: pool %p: pr_itemsperpage is zero, " |
|
"pool not initialized?", pp); |
if (__predict_false(curlwp == 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 797 pool_get(struct pool *pp, int flags) |
|
Line 931 pool_get(struct pool *pp, int flags) |
|
/* Start the allocation process over. */ |
/* Start the allocation process over. */ |
goto startover; |
goto startover; |
} |
} |
if (__predict_false((v = pi = TAILQ_FIRST(&ph->ph_itemlist)) == NULL)) { |
if (pp->pr_roflags & PR_NOTOUCH) { |
pr_leave(pp); |
|
simple_unlock(&pp->pr_slock); |
|
panic("pool_get: %s: page empty", pp->pr_wchan); |
|
} |
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (__predict_false(pp->pr_nitems == 0)) { |
if (__predict_false(ph->ph_nmissing == pp->pr_itemsperpage)) { |
pr_leave(pp); |
pr_leave(pp); |
simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
printf("pool_get: %s: items on itemlist, nitems %u\n", |
panic("pool_get: %s: page empty", pp->pr_wchan); |
pp->pr_wchan, pp->pr_nitems); |
} |
panic("pool_get: nitems inconsistent"); |
#endif |
} |
v = pr_item_notouch_get(pp, ph); |
|
#ifdef POOL_DIAGNOSTIC |
|
pr_log(pp, v, PRLOG_GET, file, line); |
|
#endif |
|
} else { |
|
v = pi = TAILQ_FIRST(&ph->ph_itemlist); |
|
if (__predict_false(v == NULL)) { |
|
pr_leave(pp); |
|
simple_unlock(&pp->pr_slock); |
|
panic("pool_get: %s: page empty", pp->pr_wchan); |
|
} |
|
#ifdef DIAGNOSTIC |
|
if (__predict_false(pp->pr_nitems == 0)) { |
|
pr_leave(pp); |
|
simple_unlock(&pp->pr_slock); |
|
printf("pool_get: %s: items on itemlist, nitems %u\n", |
|
pp->pr_wchan, pp->pr_nitems); |
|
panic("pool_get: nitems inconsistent"); |
|
} |
#endif |
#endif |
|
|
#ifdef POOL_DIAGNOSTIC |
#ifdef POOL_DIAGNOSTIC |
pr_log(pp, v, PRLOG_GET, file, line); |
pr_log(pp, v, PRLOG_GET, file, line); |
#endif |
#endif |
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (__predict_false(pi->pi_magic != PI_MAGIC)) { |
if (__predict_false(pi->pi_magic != PI_MAGIC)) { |
pr_printlog(pp, pi, printf); |
pr_printlog(pp, pi, printf); |
panic("pool_get(%s): free list modified: magic=%x; page %p;" |
panic("pool_get(%s): free list modified: " |
" item addr %p\n", |
"magic=%x; page %p; item addr %p\n", |
pp->pr_wchan, pi->pi_magic, ph->ph_page, pi); |
pp->pr_wchan, pi->pi_magic, ph->ph_page, pi); |
} |
} |
#endif |
#endif |
|
|
/* |
/* |
* Remove from item list. |
* Remove from item list. |
*/ |
*/ |
TAILQ_REMOVE(&ph->ph_itemlist, pi, pi_list); |
TAILQ_REMOVE(&ph->ph_itemlist, pi, pi_list); |
|
} |
pp->pr_nitems--; |
pp->pr_nitems--; |
pp->pr_nout++; |
pp->pr_nout++; |
if (ph->ph_nmissing == 0) { |
if (ph->ph_nmissing == 0) { |
Line 846 pool_get(struct pool *pp, int flags) |
|
Line 995 pool_get(struct pool *pp, int flags) |
|
LIST_INSERT_HEAD(&pp->pr_partpages, ph, ph_pagelist); |
LIST_INSERT_HEAD(&pp->pr_partpages, ph, ph_pagelist); |
} |
} |
ph->ph_nmissing++; |
ph->ph_nmissing++; |
if (TAILQ_EMPTY(&ph->ph_itemlist)) { |
if (ph->ph_nmissing == pp->pr_itemsperpage) { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (__predict_false(ph->ph_nmissing != pp->pr_itemsperpage)) { |
if (__predict_false((pp->pr_roflags & PR_NOTOUCH) == 0 && |
|
!TAILQ_EMPTY(&ph->ph_itemlist))) { |
pr_leave(pp); |
pr_leave(pp); |
simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
panic("pool_get: %s: nmissing inconsistent", |
panic("pool_get: %s: nmissing inconsistent", |
Line 921 pool_do_put(struct pool *pp, void *v) |
|
Line 1071 pool_do_put(struct pool *pp, void *v) |
|
/* |
/* |
* Return to item list. |
* Return to item list. |
*/ |
*/ |
|
if (pp->pr_roflags & PR_NOTOUCH) { |
|
pr_item_notouch_put(pp, ph, v); |
|
} else { |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
pi->pi_magic = PI_MAGIC; |
pi->pi_magic = PI_MAGIC; |
#endif |
#endif |
#ifdef DEBUG |
#ifdef DEBUG |
{ |
{ |
int i, *ip = v; |
int i, *ip = v; |
|
|
for (i = 0; i < pp->pr_size / sizeof(int); i++) { |
for (i = 0; i < pp->pr_size / sizeof(int); i++) { |
*ip++ = PI_MAGIC; |
*ip++ = PI_MAGIC; |
|
} |
} |
} |
} |
|
#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); |
KDASSERT(ph->ph_nmissing != 0); |
ph->ph_nmissing--; |
ph->ph_nmissing--; |
pp->pr_nput++; |
pp->pr_nput++; |
Line 957 pool_do_put(struct pool *pp, void *v) |
|
Line 1111 pool_do_put(struct pool *pp, void *v) |
|
* If this page is now empty, do one of two things: |
* If this page is now empty, do one of two things: |
* |
* |
* (1) If we have more pages than the page high water mark, |
* (1) If we have more pages than the page high water mark, |
* or if we are flagged as immediately freeing back idle |
* free the page back to the system. ONLY CONSIDER |
* pages, free the page back to the system. ONLY CONSIDER |
|
* FREEING BACK A PAGE IF WE HAVE MORE THAN OUR MINIMUM PAGE |
* FREEING BACK A PAGE IF WE HAVE MORE THAN OUR MINIMUM PAGE |
* CLAIM. |
* CLAIM. |
* |
* |
Line 971 pool_do_put(struct pool *pp, void *v) |
|
Line 1124 pool_do_put(struct pool *pp, void *v) |
|
pp->pr_nidle++; |
pp->pr_nidle++; |
if (pp->pr_npages > pp->pr_minpages && |
if (pp->pr_npages > pp->pr_minpages && |
(pp->pr_npages > pp->pr_maxpages || |
(pp->pr_npages > pp->pr_maxpages || |
(pp->pr_roflags & PR_IMMEDRELEASE) != 0 || |
|
(pp->pr_alloc->pa_flags & PA_WANT) != 0)) { |
(pp->pr_alloc->pa_flags & PA_WANT) != 0)) { |
simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
pr_rmpage(pp, ph, NULL); |
pr_rmpage(pp, ph, NULL); |
Line 1138 pool_prime_page(struct pool *pp, caddr_t |
|
Line 1290 pool_prime_page(struct pool *pp, caddr_t |
|
n = pp->pr_itemsperpage; |
n = pp->pr_itemsperpage; |
pp->pr_nitems += n; |
pp->pr_nitems += n; |
|
|
while (n--) { |
if (pp->pr_roflags & PR_NOTOUCH) { |
pi = (struct pool_item *)cp; |
pool_item_freelist_t *freelist = PR_FREELIST(ph); |
|
int i; |
|
|
|
ph->ph_off = cp - storage; |
|
ph->ph_firstfree = 0; |
|
for (i = 0; i < n - 1; i++) |
|
freelist[i] = i + 1; |
|
freelist[n - 1] = PR_INDEX_EOL; |
|
} else { |
|
while (n--) { |
|
pi = (struct pool_item *)cp; |
|
|
KASSERT(((((vaddr_t)pi) + ioff) & (align - 1)) == 0); |
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 |
pi->pi_magic = PI_MAGIC; |
pi->pi_magic = PI_MAGIC; |
#endif |
#endif |
cp = (caddr_t)(cp + pp->pr_size); |
cp = (caddr_t)(cp + pp->pr_size); |
|
} |
} |
} |
|
|
/* |
/* |
Line 1347 pool_reclaim(struct pool *pp) |
|
Line 1510 pool_reclaim(struct pool *pp) |
|
continue; |
continue; |
} |
} |
s = splvm(); |
s = splvm(); |
pool_put(&phpool, ph); |
pool_put(pp->pr_phpool, ph); |
splx(s); |
splx(s); |
} |
} |
|
|
Line 1431 pool_printit(struct pool *pp, const char |
|
Line 1594 pool_printit(struct pool *pp, const char |
|
} |
} |
|
|
static void |
static void |
pool_print_pagelist(struct pool_pagelist *pl, void (*pr)(const char *, ...)) |
pool_print_pagelist(struct pool *pp, struct pool_pagelist *pl, |
|
void (*pr)(const char *, ...)) |
{ |
{ |
struct pool_item_header *ph; |
struct pool_item_header *ph; |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
Line 1444 pool_print_pagelist(struct pool_pagelist |
|
Line 1608 pool_print_pagelist(struct pool_pagelist |
|
(u_long)ph->ph_time.tv_sec, |
(u_long)ph->ph_time.tv_sec, |
(u_long)ph->ph_time.tv_usec); |
(u_long)ph->ph_time.tv_usec); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
TAILQ_FOREACH(pi, &ph->ph_itemlist, pi_list) { |
if (!(pp->pr_roflags & PR_NOTOUCH)) { |
if (pi->pi_magic != PI_MAGIC) { |
TAILQ_FOREACH(pi, &ph->ph_itemlist, pi_list) { |
(*pr)("\t\t\titem %p, magic 0x%x\n", |
if (pi->pi_magic != PI_MAGIC) { |
pi, pi->pi_magic); |
(*pr)("\t\t\titem %p, magic 0x%x\n", |
|
pi, pi->pi_magic); |
|
} |
} |
} |
} |
} |
#endif |
#endif |
Line 1491 pool_print1(struct pool *pp, const char |
|
Line 1657 pool_print1(struct pool *pp, const char |
|
|
|
if ((ph = LIST_FIRST(&pp->pr_emptypages)) != NULL) |
if ((ph = LIST_FIRST(&pp->pr_emptypages)) != NULL) |
(*pr)("\n\tempty page list:\n"); |
(*pr)("\n\tempty page list:\n"); |
pool_print_pagelist(&pp->pr_emptypages, pr); |
pool_print_pagelist(pp, &pp->pr_emptypages, pr); |
if ((ph = LIST_FIRST(&pp->pr_fullpages)) != NULL) |
if ((ph = LIST_FIRST(&pp->pr_fullpages)) != NULL) |
(*pr)("\n\tfull page list:\n"); |
(*pr)("\n\tfull page list:\n"); |
pool_print_pagelist(&pp->pr_fullpages, pr); |
pool_print_pagelist(pp, &pp->pr_fullpages, pr); |
if ((ph = LIST_FIRST(&pp->pr_partpages)) != NULL) |
if ((ph = LIST_FIRST(&pp->pr_partpages)) != NULL) |
(*pr)("\n\tpartial-page list:\n"); |
(*pr)("\n\tpartial-page list:\n"); |
pool_print_pagelist(&pp->pr_partpages, pr); |
pool_print_pagelist(pp, &pp->pr_partpages, pr); |
|
|
if (pp->pr_curpage == NULL) |
if (pp->pr_curpage == NULL) |
(*pr)("\tno current page\n"); |
(*pr)("\tno current page\n"); |
Line 1563 pool_chk_page(struct pool *pp, const cha |
|
Line 1729 pool_chk_page(struct pool *pp, const cha |
|
return 1; |
return 1; |
} |
} |
|
|
|
if ((pp->pr_roflags & PR_NOTOUCH) != 0) |
|
return 0; |
|
|
for (pi = TAILQ_FIRST(&ph->ph_itemlist), n = 0; |
for (pi = TAILQ_FIRST(&ph->ph_itemlist), n = 0; |
pi != NULL; |
pi != NULL; |
pi = TAILQ_NEXT(pi,pi_list), n++) { |
pi = TAILQ_NEXT(pi,pi_list), n++) { |
Line 2082 pool_page_alloc(struct pool *pp, int fla |
|
Line 2251 pool_page_alloc(struct pool *pp, int fla |
|
{ |
{ |
boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE; |
boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE; |
|
|
return ((void *) uvm_km_alloc_poolpage(waitok)); |
return ((void *) uvm_km_alloc_poolpage_cache(kmem_map, waitok)); |
} |
} |
|
|
void |
void |
pool_page_free(struct pool *pp, void *v) |
pool_page_free(struct pool *pp, void *v) |
{ |
{ |
|
|
uvm_km_free_poolpage((vaddr_t) v); |
uvm_km_free_poolpage_cache(kmem_map, (vaddr_t) v); |
|
} |
|
|
|
static void * |
|
pool_page_alloc_meta(struct pool *pp, int flags) |
|
{ |
|
boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE; |
|
|
|
return ((void *) uvm_km_alloc_poolpage(kmem_map, waitok)); |
|
} |
|
|
|
static void |
|
pool_page_free_meta(struct pool *pp, void *v) |
|
{ |
|
|
|
uvm_km_free_poolpage(kmem_map, (vaddr_t) v); |
} |
} |
|
|
#ifdef POOL_SUBPAGE |
#ifdef POOL_SUBPAGE |
Line 2134 pool_page_alloc_nointr(struct pool *pp, |
|
Line 2318 pool_page_alloc_nointr(struct pool *pp, |
|
{ |
{ |
boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE; |
boolean_t waitok = (flags & PR_WAITOK) ? TRUE : FALSE; |
|
|
return ((void *) uvm_km_alloc_poolpage1(kernel_map, |
return ((void *) uvm_km_alloc_poolpage_cache(kernel_map, waitok)); |
uvm.kernel_object, waitok)); |
|
} |
} |
|
|
void |
void |
pool_page_free_nointr(struct pool *pp, void *v) |
pool_page_free_nointr(struct pool *pp, void *v) |
{ |
{ |
|
|
uvm_km_free_poolpage1(kernel_map, (vaddr_t) v); |
uvm_km_free_poolpage_cache(kernel_map, (vaddr_t) v); |
} |
} |
#endif /* POOL_SUBPAGE */ |
#endif /* POOL_SUBPAGE */ |