| version 1.54, 2001/05/10 02:19:32 |
version 1.55, 2001/05/10 04:51:41 |
| Line 148 struct pool_cache_group { |
|
| Line 148 struct pool_cache_group { |
|
| static void pool_cache_reclaim(struct pool_cache *); |
static void pool_cache_reclaim(struct pool_cache *); |
| |
|
| static int pool_catchup(struct pool *); |
static int pool_catchup(struct pool *); |
| static int pool_prime_page(struct pool *, caddr_t, int); |
static void pool_prime_page(struct pool *, caddr_t, |
| |
struct pool_item_header *); |
| static void *pool_page_alloc(unsigned long, int, int); |
static void *pool_page_alloc(unsigned long, int, int); |
| static void pool_page_free(void *, unsigned long, int); |
static void pool_page_free(void *, unsigned long, int); |
| |
|
| Line 548 pool_destroy(struct pool *pp) |
|
| Line 549 pool_destroy(struct pool *pp) |
|
| free(pp, M_POOL); |
free(pp, M_POOL); |
| } |
} |
| |
|
| |
static __inline struct pool_item_header * |
| |
pool_alloc_item_header(struct pool *pp, caddr_t storage, int flags) |
| |
{ |
| |
struct pool_item_header *ph; |
| |
int s; |
| |
|
| |
LOCK_ASSERT(simple_lock_held(&pp->pr_slock) == 0); |
| |
|
| |
if ((pp->pr_roflags & PR_PHINPAGE) != 0) |
| |
ph = (struct pool_item_header *) (storage + pp->pr_phoffset); |
| |
else { |
| |
s = splhigh(); |
| |
ph = pool_get(&phpool, flags); |
| |
splx(s); |
| |
} |
| |
|
| |
return (ph); |
| |
} |
| |
|
| /* |
/* |
| * Grab an item from the pool; must be called at appropriate spl level |
* Grab an item from the pool; must be called at appropriate spl level |
| Line 555 pool_destroy(struct pool *pp) |
|
| Line 574 pool_destroy(struct pool *pp) |
|
| void * |
void * |
| _pool_get(struct pool *pp, int flags, const char *file, long line) |
_pool_get(struct pool *pp, int flags, const char *file, long line) |
| { |
{ |
| void *v; |
|
| struct pool_item *pi; |
struct pool_item *pi; |
| struct pool_item_header *ph; |
struct pool_item_header *ph; |
| |
void *v; |
| |
|
| #ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
| if (__predict_false((pp->pr_roflags & PR_STATIC) && |
if (__predict_false((pp->pr_roflags & PR_STATIC) && |
| Line 625 _pool_get(struct pool *pp, int flags, co |
|
| Line 644 _pool_get(struct pool *pp, int flags, co |
|
| * has no items in its bucket. |
* has no items in its bucket. |
| */ |
*/ |
| if ((ph = pp->pr_curpage) == NULL) { |
if ((ph = pp->pr_curpage) == NULL) { |
| void *v; |
|
| |
|
| #ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
| if (pp->pr_nitems != 0) { |
if (pp->pr_nitems != 0) { |
| simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
| Line 644 _pool_get(struct pool *pp, int flags, co |
|
| Line 661 _pool_get(struct pool *pp, int flags, co |
|
| pr_leave(pp); |
pr_leave(pp); |
| simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
| v = (*pp->pr_alloc)(pp->pr_pagesz, flags, pp->pr_mtype); |
v = (*pp->pr_alloc)(pp->pr_pagesz, flags, pp->pr_mtype); |
| |
if (__predict_true(v != NULL)) |
| |
ph = pool_alloc_item_header(pp, v, flags); |
| simple_lock(&pp->pr_slock); |
simple_lock(&pp->pr_slock); |
| pr_enter(pp, file, line); |
pr_enter(pp, file, line); |
| |
|
| if (v == NULL) { |
if (__predict_false(v == NULL || ph == NULL)) { |
| |
if (v != NULL) |
| |
(*pp->pr_free)(v, pp->pr_pagesz, pp->pr_mtype); |
| |
|
| /* |
/* |
| * We were unable to allocate a page, but |
* We were unable to allocate a page or item |
| * we released the lock during allocation, |
* header, but we released the lock during |
| * so perhaps items were freed back to the |
* allocation, so perhaps items were freed |
| * pool. Check for this case. |
* back to the pool. Check for this case. |
| */ |
*/ |
| if (pp->pr_curpage != NULL) |
if (pp->pr_curpage != NULL) |
| goto startover; |
goto startover; |
| Line 686 _pool_get(struct pool *pp, int flags, co |
|
| Line 708 _pool_get(struct pool *pp, int flags, co |
|
| } |
} |
| |
|
| /* We have more memory; add it to the pool */ |
/* We have more memory; add it to the pool */ |
| if (pool_prime_page(pp, v, flags & PR_WAITOK) != 0) { |
pool_prime_page(pp, v, ph); |
| /* |
|
| * Probably, we don't allowed to wait and |
|
| * couldn't allocate a page header. |
|
| */ |
|
| (*pp->pr_free)(v, pp->pr_pagesz, pp->pr_mtype); |
|
| pp->pr_nfail++; |
|
| pr_leave(pp); |
|
| simple_unlock(&pp->pr_slock); |
|
| return (NULL); |
|
| } |
|
| pp->pr_npagealloc++; |
pp->pr_npagealloc++; |
| |
|
| /* Start the allocation process over. */ |
/* Start the allocation process over. */ |
| Line 938 _pool_put(struct pool *pp, void *v, cons |
|
| Line 950 _pool_put(struct pool *pp, void *v, cons |
|
| } |
} |
| |
|
| /* |
/* |
| |
* Add N items to the pool. |
| |
*/ |
| |
int |
| |
pool_prime(struct pool *pp, int n) |
| |
{ |
| |
struct pool_item_header *ph; |
| |
caddr_t cp; |
| |
int newpages, error = 0; |
| |
|
| |
simple_lock(&pp->pr_slock); |
| |
|
| |
newpages = roundup(n, pp->pr_itemsperpage) / pp->pr_itemsperpage; |
| |
|
| |
while (newpages-- > 0) { |
| |
simple_unlock(&pp->pr_slock); |
| |
cp = (*pp->pr_alloc)(pp->pr_pagesz, PR_NOWAIT, pp->pr_mtype); |
| |
if (__predict_true(cp != NULL)) |
| |
ph = pool_alloc_item_header(pp, cp, PR_NOWAIT); |
| |
simple_lock(&pp->pr_slock); |
| |
|
| |
if (__predict_false(cp == NULL || ph == NULL)) { |
| |
error = ENOMEM; |
| |
if (cp != NULL) |
| |
(*pp->pr_free)(cp, pp->pr_pagesz, pp->pr_mtype); |
| |
break; |
| |
} |
| |
|
| |
pool_prime_page(pp, cp, ph); |
| |
pp->pr_npagealloc++; |
| |
pp->pr_minpages++; |
| |
} |
| |
|
| |
if (pp->pr_minpages >= pp->pr_maxpages) |
| |
pp->pr_maxpages = pp->pr_minpages + 1; /* XXX */ |
| |
|
| |
simple_unlock(&pp->pr_slock); |
| |
return (0); |
| |
} |
| |
|
| |
/* |
| * Add a page worth of items to the pool. |
* Add a page worth of items to the pool. |
| * |
* |
| * Note, we must be called with the pool descriptor LOCKED. |
* Note, we must be called with the pool descriptor LOCKED. |
| */ |
*/ |
| static int |
static void |
| pool_prime_page(struct pool *pp, caddr_t storage, int flags) |
pool_prime_page(struct pool *pp, caddr_t storage, struct pool_item_header *ph) |
| { |
{ |
| struct pool_item *pi; |
struct pool_item *pi; |
| struct pool_item_header *ph; |
|
| caddr_t cp = storage; |
caddr_t cp = storage; |
| unsigned int align = pp->pr_align; |
unsigned int align = pp->pr_align; |
| unsigned int ioff = pp->pr_itemoffset; |
unsigned int ioff = pp->pr_itemoffset; |
| int s, n; |
int n; |
| |
|
| if (((u_long)cp & (pp->pr_pagesz - 1)) != 0) |
if (((u_long)cp & (pp->pr_pagesz - 1)) != 0) |
| panic("pool_prime_page: %s: unaligned page", pp->pr_wchan); |
panic("pool_prime_page: %s: unaligned page", pp->pr_wchan); |
| |
|
| if ((pp->pr_roflags & PR_PHINPAGE) != 0) { |
if ((pp->pr_roflags & PR_PHINPAGE) == 0) |
| ph = (struct pool_item_header *)(cp + pp->pr_phoffset); |
|
| } else { |
|
| s = splhigh(); |
|
| ph = pool_get(&phpool, flags); |
|
| splx(s); |
|
| if (ph == NULL) |
|
| return (ENOMEM); |
|
| LIST_INSERT_HEAD(&pp->pr_hashtab[PR_HASH_INDEX(pp, cp)], |
LIST_INSERT_HEAD(&pp->pr_hashtab[PR_HASH_INDEX(pp, cp)], |
| ph, ph_hashlist); |
ph, ph_hashlist); |
| } |
|
| |
|
| /* |
/* |
| * Insert page header. |
* Insert page header. |
| Line 1016 pool_prime_page(struct pool *pp, caddr_t |
|
| Line 1059 pool_prime_page(struct pool *pp, caddr_t |
|
| |
|
| if (++pp->pr_npages > pp->pr_hiwat) |
if (++pp->pr_npages > pp->pr_hiwat) |
| pp->pr_hiwat = pp->pr_npages; |
pp->pr_hiwat = pp->pr_npages; |
| |
|
| return (0); |
|
| } |
} |
| |
|
| /* |
/* |
| Line 1034 pool_prime_page(struct pool *pp, caddr_t |
|
| Line 1075 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; |
| caddr_t cp; |
caddr_t cp; |
| int error = 0; |
int error = 0; |
| |
|
| Line 1057 pool_catchup(struct pool *pp) |
|
| Line 1099 pool_catchup(struct pool *pp) |
|
| * the pool descriptor? |
* the pool descriptor? |
| */ |
*/ |
| simple_unlock(&pp->pr_slock); |
simple_unlock(&pp->pr_slock); |
| cp = (*pp->pr_alloc)(pp->pr_pagesz, 0, pp->pr_mtype); |
cp = (*pp->pr_alloc)(pp->pr_pagesz, PR_NOWAIT, pp->pr_mtype); |
| |
if (__predict_true(cp != NULL)) |
| |
ph = pool_alloc_item_header(pp, cp, PR_NOWAIT); |
| simple_lock(&pp->pr_slock); |
simple_lock(&pp->pr_slock); |
| if (__predict_false(cp == NULL)) { |
if (__predict_false(cp == NULL || ph == NULL)) { |
| |
if (cp != NULL) |
| |
(*pp->pr_free)(cp, pp->pr_pagesz, pp->pr_mtype); |
| error = ENOMEM; |
error = ENOMEM; |
| break; |
break; |
| } |
} |
| if ((error = pool_prime_page(pp, cp, PR_NOWAIT)) != 0) { |
pool_prime_page(pp, cp, ph); |
| (*pp->pr_free)(cp, pp->pr_pagesz, pp->pr_mtype); |
|
| break; |
|
| } |
|
| pp->pr_npagealloc++; |
pp->pr_npagealloc++; |
| } |
} |
| |
|