]> granicus.if.org Git - zfs/commitdiff
Allow joinable threads
authorBrian Behlendorf <behlendorf1@llnl.gov>
Sun, 27 Jun 2010 22:06:49 +0000 (15:06 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 28 Jun 2010 17:15:29 +0000 (10:15 -0700)
There was previous discussion of a race with joinable threads but to
be honest I can neither exactly remember the race, or recrease the
issue.  I believe it may have had to do with pthread_create() returning
without having set kt->tid since this was done in the created thread.
If that was the race then I've 'fixed' it by ensuring the thread id
is set in the thread AND as the first pthread_create() argument.  Why
this wasn't done originally I'm not sure, with luck Ricardo remembers.

Additionally, explicitly set a PAGESIZE guard frame at the end of the
stack to aid in detecting stack overflow.  And add some conditional
logic to set STACK_SIZE correctly for Solaris.

lib/libzpool/include/sys/zfs_context.h
lib/libzpool/kernel.c

index db93a89b8bf04b0ec0f48bcd59bc4c51dbed3c8a..e62c75a1888d2fd595fc40374d9096919a265707 100644 (file)
@@ -198,7 +198,11 @@ _NOTE(CONSTCOND) } while (0)
  * Threads
  */
 #define TS_RUN                 0x00000002
+#ifdef _linux_
 #define        STACK_SIZE              8192    /* Linux x86 and amd64 */
+#else
+#define        STACK_SIZE              24576   /* Solaris */
+#endif
 
 /* in libzpool, p0 exists only to have its address taken */
 typedef struct proc {
index 6f9e383a87296705298e5907083d4e6e305fd786..a992bec9ab7b9671b173879243b6c7f1b8fb34ab 100644 (file)
@@ -145,14 +145,9 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
              size_t len, proc_t *pp, int state, pri_t pri)
 {
        kthread_t *kt;
-       pthread_t tid;
        pthread_attr_t attr;
        size_t stack;
 
-       /*
-        * Due to a race when getting/setting the thread ID, currently only
-        * detached threads are supported.
-        */
        ASSERT3S(state & ~TS_RUN, ==, 0);
 
        kt = umem_zalloc(sizeof(kthread_t), UMEM_NOFAIL);
@@ -160,23 +155,23 @@ zk_thread_create(caddr_t stk, size_t stksize, thread_func_t func, void *arg,
        kt->t_arg = arg;
 
        /*
-        * The Solaris kernel stack size in x86/x64 is 8K, so we reduce the
-        * default stack size in userspace, for sanity checking.
-        *
-        * PTHREAD_STACK_MIN is the stack required for a NULL procedure in
-        * userspace.
+        * The Solaris kernel stack size is 24k for x86/x86_64.
+        * The Linux kernel stack size is 8k for x86/x86_64.
         *
-        * XXX: Stack size for other architectures is not being taken into
-        * account.
+        * We reduce the default stack size in userspace, to ensure
+        * we observe stack overruns in user space as well as in
+        * 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.
         */
        stack = PTHREAD_STACK_MIN + MAX(stksize, STACK_SIZE);
 
        VERIFY3S(pthread_attr_init(&attr), ==, 0);
        VERIFY3S(pthread_attr_setstacksize(&attr, stack), ==, 0);
-       VERIFY3S(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED),
-           ==, 0);
+       VERIFY3S(pthread_attr_setguardsize(&attr, PAGESIZE), ==, 0);
 
-       VERIFY3S(pthread_create(&tid, &attr, &zk_thread_helper, kt), ==, 0);
+       VERIFY3S(pthread_create(&kt->t_tid, &attr, &zk_thread_helper, kt),
+           ==, 0);
 
        VERIFY3S(pthread_attr_destroy(&attr), ==, 0);