Index: sys/kern/subr_pool.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_pool.c,v retrieving revision 1.218 diff -p -u -r1.218 subr_pool.c --- sys/kern/subr_pool.c 4 Dec 2017 03:05:24 -0000 1.218 +++ sys/kern/subr_pool.c 5 Dec 2017 19:54:03 -0000 @@ -1073,10 +1073,22 @@ pool_grow(struct pool *pp, int flags) } while (pp->pr_flags & PR_GROWING); return ERESTART; } else { + if (pp->pr_flags & PR_GROWINGNOWAIT) { + /* + * This needs an unlock/relock dance so + * that the other caller has a chance to + * run and actually do the thing. + */ + mutex_exit(&pp->pr_lock); + mutex_enter(&pp->pr_lock); + return ERESTART; + } return EWOULDBLOCK; } } pp->pr_flags |= PR_GROWING; + if ((flags & PR_WAITOK) == 0) + pp->pr_flags |= PR_GROWINGNOWAIT; mutex_exit(&pp->pr_lock); char *cp = pool_allocator_alloc(pp, flags); @@ -1093,7 +1105,7 @@ pool_grow(struct pool *pp, int flags) pool_prime_page(pp, cp, ph); pp->pr_npagealloc++; KASSERT(pp->pr_flags & PR_GROWING); - pp->pr_flags &= ~PR_GROWING; + pp->pr_flags &= ~(PR_GROWING|PR_GROWINGNOWAIT); /* * If anyone was waiting for pool_grow, notify them that we * may have just done it. @@ -1102,7 +1114,7 @@ pool_grow(struct pool *pp, int flags) return 0; out: KASSERT(pp->pr_flags & PR_GROWING); - pp->pr_flags &= ~PR_GROWING; + pp->pr_flags &= ~(PR_GROWING|PR_GROWINGNOWAIT); mutex_enter(&pp->pr_lock); return ENOMEM; } Index: sys/sys/pool.h =================================================================== RCS file: /cvsroot/src/sys/sys/pool.h,v retrieving revision 1.81 diff -p -u -r1.81 pool.h --- sys/sys/pool.h 2 Dec 2017 08:15:43 -0000 1.81 +++ sys/sys/pool.h 5 Dec 2017 19:54:03 -0000 @@ -148,6 +148,7 @@ struct pool { #define PR_NOALIGN 0x800 /* don't assume backend alignment */ #define PR_LARGECACHE 0x1000 /* use large cache groups */ #define PR_GROWING 0x2000 /* pool_grow in progress */ +#define PR_GROWINGNOWAIT 0x4000 /* pool_grow in progress by PR_NOWAIT alloc */ /* * `pr_lock' protects the pool's data structures when removing