]> granicus.if.org Git - zfs/commitdiff
Add extra guard space if needed
authorNed Bass <bass6@llnl.gov>
Thu, 22 Jul 2010 01:53:14 +0000 (18:53 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 23 Jul 2010 18:38:00 +0000 (11:38 -0700)
Some buggy NPTL threading implementations include the guard area within
the stack size allocations.  In this case we need to allocate an extra
page to account for the guard area since we only have two pages of usable
stack on Linux.  Added an autoconf test that detects such implementations
by running a test program designed to segfault if the bug is present.
Set a flag NPTL_GUARD_WITHIN_STACK that is tested to decide if extra
stack space must be allocated for the guard area.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
lib/libzpool/include/sys/zfs_context.h
lib/libzpool/kernel.c

index f837440c06de8a5f3ed298ce6b54f917e46ff2b4..e211286c6b594bbc7cdb0804508a0202f391afb2 100644 (file)
@@ -205,6 +205,12 @@ _NOTE(CONSTCOND) } while (0)
 #define        STACK_SIZE              24576   /* Solaris */
 #endif
 
+#ifdef NPTL_GUARD_WITHIN_STACK
+#define        EXTRA_GUARD_BYTES       PAGESIZE
+#else
+#define        EXTRA_GUARD_BYTES       0
+#endif
+
 /* in libzpool, p0 exists only to have its address taken */
 typedef struct proc {
        uintptr_t       this_is_never_used_dont_dereference_it;
index 2c9d32be82d9643b05f169dcad7f67844c6da8a2..04f4bf3548de31e34b1c19801656cae4b5f2353b 100644 (file)
@@ -163,8 +163,16 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
         * kernel space.  PTHREAD_STACK_MIN is the minimum stack
         * required for a NULL procedure in user space and is added
         * in to the stack requirements.
+        *
+        * Some buggy NPTL threading implementations include the
+        * guard area within the stack size allocations.  In
+        * this case we allocate an extra page to account for the
+        * guard area since we only have two pages of usable stack
+        * on Linux.
         */
-       stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE);
+
+       stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE) +
+                       EXTRA_GUARD_BYTES;
 
        VERIFY3S(pthread_attr_init(&attr), ==, 0);
        VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);