Module Name: src Committed By: mrg Date: Sat Dec 16 03:13:29 UTC 2017
Modified Files: src/sys/kern: subr_pool.c src/sys/sys: pool.h Log Message: hopefully workaround the irregularly "fork fails in init" problem. if a pool is growing, and the grower is PR_NOWAIT, mark this. if another caller wants to grow the pool and is also PR_NOWAIT, busy-wait for the original caller, which should either succeed or hard-fail fairly quickly. implement the busy-wait by unlocking and relocking this pools mutex and returning ERESTART. other methods (such as having the caller do this) were significantly more code and this hack is fairly localised. ok chs@ riastradh@ To generate a diff of this commit: cvs rdiff -u -r1.218 -r1.219 src/sys/kern/subr_pool.c cvs rdiff -u -r1.81 -r1.82 src/sys/sys/pool.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_pool.c diff -u src/sys/kern/subr_pool.c:1.218 src/sys/kern/subr_pool.c:1.219 --- src/sys/kern/subr_pool.c:1.218 Mon Dec 4 03:05:24 2017 +++ src/sys/kern/subr_pool.c Sat Dec 16 03:13:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_pool.c,v 1.218 2017/12/04 03:05:24 mrg Exp $ */ +/* $NetBSD: subr_pool.c,v 1.219 2017/12/16 03:13:29 mrg Exp $ */ /*- * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015 @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.218 2017/12/04 03:05:24 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.219 2017/12/16 03:13:29 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1073,10 +1073,23 @@ 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. Note + * that this is effectively a busy-wait. + */ + 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 +1106,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 +1115,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: src/sys/sys/pool.h diff -u src/sys/sys/pool.h:1.81 src/sys/sys/pool.h:1.82 --- src/sys/sys/pool.h:1.81 Sat Dec 2 08:15:43 2017 +++ src/sys/sys/pool.h Sat Dec 16 03:13:29 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pool.h,v 1.81 2017/12/02 08:15:43 mrg Exp $ */ +/* $NetBSD: pool.h,v 1.82 2017/12/16 03:13:29 mrg Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2000, 2007 The NetBSD Foundation, Inc. @@ -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