diff --git a/lib/libzpool/include/sys/zfs_context.h b/lib/libzpool/include/sys/zfs_context.h index f837440c06..e211286c6b 100644 --- a/lib/libzpool/include/sys/zfs_context.h +++ b/lib/libzpool/include/sys/zfs_context.h @@ -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; diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c index 2c9d32be82..04f4bf3548 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -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);