From 616df2dd8bf76e6eb73b546d75e4c4291e104ecf Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Mon, 28 Jun 2010 12:34:20 -0700 Subject: [PATCH] Fix subtle race in threads test case The call to wake_up() must be moved under the spin lock because once we drop the lock 'tp' may no longer be valid because the creating thread has exited. This basic thread implementation was correct, this was simply a flaw in the test case. --- module/splat/splat-thread.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/module/splat/splat-thread.c b/module/splat/splat-thread.c index d21ded7959..34810bfffc 100644 --- a/module/splat/splat-thread.c +++ b/module/splat/splat-thread.c @@ -67,9 +67,9 @@ splat_thread_work1(void *priv) spin_lock(&tp->tp_lock); ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC); tp->tp_rc = 1; + wake_up(&tp->tp_waitq); spin_unlock(&tp->tp_lock); - wake_up(&tp->tp_waitq); thread_exit(); } @@ -108,18 +108,17 @@ splat_thread_work2(void *priv) spin_lock(&tp->tp_lock); ASSERT(tp->tp_magic == SPLAT_THREAD_TEST_MAGIC); tp->tp_rc = 1; + wake_up(&tp->tp_waitq); spin_unlock(&tp->tp_lock); - wake_up(&tp->tp_waitq); thread_exit(); /* The following code is unreachable when thread_exit() is * working properly, which is exactly what we're testing */ spin_lock(&tp->tp_lock); tp->tp_rc = 2; - spin_unlock(&tp->tp_lock); - wake_up(&tp->tp_waitq); + spin_unlock(&tp->tp_lock); } static int