Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys hopefully workaround the irregularly "fork fails in init...



details:   https://anonhg.NetBSD.org/src/rev/f6ed832f74b9
branches:  trunk
changeset: 358178:f6ed832f74b9
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sat Dec 16 03:13:29 2017 +0000

description:
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@

diffstat:

 sys/kern/subr_pool.c |  21 +++++++++++++++++----
 sys/sys/pool.h       |   3 ++-
 2 files changed, 19 insertions(+), 5 deletions(-)

diffs (77 lines):

diff -r fbafd4c4a859 -r f6ed832f74b9 sys/kern/subr_pool.c
--- a/sys/kern/subr_pool.c      Sat Dec 16 02:45:14 2017 +0000
+++ b/sys/kern/subr_pool.c      Sat Dec 16 03:13:29 2017 +0000
@@ -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 @@
                        } 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_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 @@
        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;
 }
diff -r fbafd4c4a859 -r f6ed832f74b9 sys/sys/pool.h
--- a/sys/sys/pool.h    Sat Dec 16 02:45:14 2017 +0000
+++ b/sys/sys/pool.h    Sat Dec 16 03:13:29 2017 +0000
@@ -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 @@
 #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



Home | Main Index | Thread Index | Old Index