diff --git a/lib/libzpool/include/sys/zfs_context.h b/lib/libzpool/include/sys/zfs_context.h index fad26f3e94..3f5a078ecc 100644 --- a/lib/libzpool/include/sys/zfs_context.h +++ b/lib/libzpool/include/sys/zfs_context.h @@ -211,6 +211,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 4fa55f03b1..81c149820e 100644 --- a/lib/libzpool/kernel.c +++ b/lib/libzpool/kernel.c @@ -162,8 +162,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);