Index: subr_pool.c =================================================================== RCS file: /cvs/src/sys/kern/subr_pool.c,v retrieving revision 1.165 diff -u -p -r1.165 subr_pool.c --- subr_pool.c 10 Nov 2014 18:55:43 -0000 1.165 +++ subr_pool.c 14 Nov 2014 02:32:43 -0000 @@ -105,13 +105,13 @@ int pool_debug = 0; #define POOL_INPGHDR(pp) ((pp)->pr_phoffset != 0) struct pool_item_header * - pool_p_alloc(struct pool *, int); + pool_p_alloc(struct pool *, int, int *); void pool_p_insert(struct pool *, struct pool_item_header *); void pool_p_remove(struct pool *, struct pool_item_header *); void pool_p_free(struct pool *, struct pool_item_header *); void pool_update_curpage(struct pool *); -void *pool_do_get(struct pool *, int); +void *pool_do_get(struct pool *, int, int *); int pool_chk_page(struct pool *, struct pool_item_header *, int); int pool_chk(struct pool *); void pool_get_done(void *, void *); @@ -416,6 +416,7 @@ void * pool_get(struct pool *pp, int flags) { void *v = NULL; + int slowdown = 0; KASSERT(flags & (PR_WAITOK | PR_NOWAIT)); @@ -424,12 +425,15 @@ pool_get(struct pool *pp, int flags) if (pp->pr_nout >= pp->pr_hardlimit) { if (ISSET(flags, PR_NOWAIT|PR_LIMITFAIL)) goto fail; - } else if ((v = pool_do_get(pp, flags)) == NULL) { + } else if ((v = pool_do_get(pp, flags, &slowdown)) == NULL) { if (ISSET(flags, PR_NOWAIT)) goto fail; } mtx_leave(&pp->pr_mtx); + if (slowdown && ISSET(flags, PR_WAITOK)) + yield(); + if (v == NULL) { struct pool_get_memory mem = { MUTEX_INITIALIZER(pp->pr_ipl), NULL }; @@ -497,11 +501,13 @@ pool_runqueue(struct pool *pp, int flags mtx_enter(&pp->pr_mtx); pr = TAILQ_FIRST(&prl); while (pr != NULL) { + int slowdown = 0; + if (pp->pr_nout >= pp->pr_hardlimit) break; - pr->pr_item = pool_do_get(pp, flags); - if (pr->pr_item == NULL) + pr->pr_item = pool_do_get(pp, flags, &slowdown); + if (pr->pr_item == NULL) /* || slowdown ? */ break; pr = TAILQ_NEXT(pr, pr_entry); @@ -525,7 +531,7 @@ pool_runqueue(struct pool *pp, int flags } void * -pool_do_get(struct pool *pp, int flags) +pool_do_get(struct pool *pp, int flags, int *slowdown) { struct pool_item *pi; struct pool_item_header *ph; @@ -540,7 +546,7 @@ pool_do_get(struct pool *pp, int flags) if (pp->pr_curpage == NULL) { mtx_leave(&pp->pr_mtx); - ph = pool_p_alloc(pp, flags); + ph = pool_p_alloc(pp, flags, slowdown); mtx_enter(&pp->pr_mtx); if (ph == NULL) { @@ -693,8 +699,10 @@ pool_prime(struct pool *pp, int n) newpages = roundup(n, pp->pr_itemsperpage) / pp->pr_itemsperpage; while (newpages-- > 0) { - ph = pool_p_alloc(pp, PR_NOWAIT); - if (ph == NULL) + int slowdown = 0; + + ph = pool_p_alloc(pp, PR_NOWAIT, &slowdown); + if (ph == NULL) /* or slowdown? */ break; LIST_INSERT_HEAD(&pl, ph, ph_pagelist); @@ -711,22 +719,19 @@ pool_prime(struct pool *pp, int n) } struct pool_item_header * -pool_p_alloc(struct pool *pp, int flags) +pool_p_alloc(struct pool *pp, int flags, int *slowdown) { struct pool_item_header *ph; struct pool_item *pi; caddr_t addr; - int n, slowdown = 0; + int n; MUTEX_ASSERT_UNLOCKED(&pp->pr_mtx); KASSERT(pp->pr_size >= sizeof(*pi)); - addr = pool_allocator_alloc(pp, flags, &slowdown); + addr = pool_allocator_alloc(pp, flags, slowdown); if (addr == NULL) return (NULL); - - if (slowdown && ISSET(flags, PR_WAITOK)) - yield(); if (POOL_INPGHDR(pp)) ph = (struct pool_item_header *)(addr + pp->pr_phoffset);