From: Jack Steiner <steiner@sgi.com>
To: torvalds@osdl.org
Cc: akpm@osdl.org, linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] - Fix memory ordering problem in wake_futex()
Date: Tue, 27 Dec 2005 16:30:59 +0000 [thread overview]
Message-ID: <20051227163059.GA2381@sgi.com> (raw)
In-Reply-To: <20051224181325.GH24601@pb15.lixom.net>
Hi Linus,
Here is a fix for a ugly race condition that occurs in wake_futex(). The
failure was detected on IA64 but may also occur on other architectures.
On IA64, locks are released using a "st.rel" instruction. This ensures that
preceding "stores" are visible before the lock is released but does NOT prevent
a "store" that follows the "st.rel" from becoming visible before the "st.rel".
The failure I saw is a task that owned a futex_q resumed prematurely and
was context-switch off of the cpu. The task's switch_stack occupied the same
space as the futex_q. The store to q->lock_ptr in futex_wait()overwrote the
ar.bspstore in the switch_stack. When the task resumed, it ran with a corrupted
ar.bspstore. Things went downhill from there.
Without the fix, the application fails roughly every 10 minutes. With
the fix, it ran over 16 hours without a failure.
----
Fix a memory ordering problem that occurs on IA64. The "store" to q->lock_ptr
in wake_futex() can become visible before wake_up_all() clears the lock in the
futex_q.
Signed-off-by: Jack Steiner <steiner@sgi.com>
Index: linux/kernel/futex.c
=================================--- linux.orig/kernel/futex.c 2005-12-24 15:09:23.381357908 -0600
+++ linux/kernel/futex.c 2005-12-24 15:14:26.362119396 -0600
@@ -262,15 +262,18 @@ static void wake_futex(struct futex_q *q
list_del_init(&q->list);
if (q->filp)
send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
- /*
- * The lock in wake_up_all() is a crucial memory barrier after the
- * list_del_init() and also before assigning to q->lock_ptr.
- */
wake_up_all(&q->waiters);
+
/*
* The waiting task can free the futex_q as soon as this is written,
* without taking any locks. This must come last.
+ *
+ * A memory barrier is required here to prevent the following store
+ * to lock_ptr from getting ahead of the wakeup. Clearing the lock
+ * at the end of wake_up_all() is not a write barrier on all
+ * architectures.
*/
+ smp_wmb();
q->lock_ptr = NULL;
}
WARNING: multiple messages have this Message-ID (diff)
From: Jack Steiner <steiner@sgi.com>
To: torvalds@osdl.org
Cc: akpm@osdl.org, linux-ia64@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] - Fix memory ordering problem in wake_futex()
Date: Tue, 27 Dec 2005 10:30:59 -0600 [thread overview]
Message-ID: <20051227163059.GA2381@sgi.com> (raw)
In-Reply-To: <20051224181325.GH24601@pb15.lixom.net>
Hi Linus,
Here is a fix for a ugly race condition that occurs in wake_futex(). The
failure was detected on IA64 but may also occur on other architectures.
On IA64, locks are released using a "st.rel" instruction. This ensures that
preceding "stores" are visible before the lock is released but does NOT prevent
a "store" that follows the "st.rel" from becoming visible before the "st.rel".
The failure I saw is a task that owned a futex_q resumed prematurely and
was context-switch off of the cpu. The task's switch_stack occupied the same
space as the futex_q. The store to q->lock_ptr in futex_wait()overwrote the
ar.bspstore in the switch_stack. When the task resumed, it ran with a corrupted
ar.bspstore. Things went downhill from there.
Without the fix, the application fails roughly every 10 minutes. With
the fix, it ran over 16 hours without a failure.
----
Fix a memory ordering problem that occurs on IA64. The "store" to q->lock_ptr
in wake_futex() can become visible before wake_up_all() clears the lock in the
futex_q.
Signed-off-by: Jack Steiner <steiner@sgi.com>
Index: linux/kernel/futex.c
===================================================================
--- linux.orig/kernel/futex.c 2005-12-24 15:09:23.381357908 -0600
+++ linux/kernel/futex.c 2005-12-24 15:14:26.362119396 -0600
@@ -262,15 +262,18 @@ static void wake_futex(struct futex_q *q
list_del_init(&q->list);
if (q->filp)
send_sigio(&q->filp->f_owner, q->fd, POLL_IN);
- /*
- * The lock in wake_up_all() is a crucial memory barrier after the
- * list_del_init() and also before assigning to q->lock_ptr.
- */
wake_up_all(&q->waiters);
+
/*
* The waiting task can free the futex_q as soon as this is written,
* without taking any locks. This must come last.
+ *
+ * A memory barrier is required here to prevent the following store
+ * to lock_ptr from getting ahead of the wakeup. Clearing the lock
+ * at the end of wake_up_all() is not a write barrier on all
+ * architectures.
*/
+ smp_wmb();
q->lock_ptr = NULL;
}
next prev parent reply other threads:[~2005-12-27 16:30 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-12-23 16:38 [PATCH] - Fix memory ordering problem in wake_futex() Jack Steiner
2005-12-23 16:38 ` Jack Steiner
2005-12-23 17:05 ` Joe Seigh
2005-12-23 20:48 ` Olof Johansson
2005-12-23 20:48 ` Olof Johansson
2005-12-23 21:32 ` Jack Steiner
2005-12-23 21:32 ` Jack Steiner
2005-12-23 21:59 ` Olof Johansson
2005-12-23 21:59 ` Olof Johansson
2005-12-23 23:48 ` Robin Holt
2005-12-23 23:48 ` Robin Holt
2005-12-24 13:45 ` Jack Steiner
2005-12-24 13:45 ` Jack Steiner
2005-12-24 18:13 ` Olof Johansson
2005-12-24 18:13 ` Olof Johansson
2005-12-27 16:30 ` Jack Steiner [this message]
2005-12-27 16:30 ` Jack Steiner
-- strict thread matches above, loose matches on Subject: below --
2005-12-23 22:23 Manfred Spraul
2005-12-23 22:52 ` Manfred Spraul
2005-12-24 3:45 ` Jack Steiner
2005-12-25 16:02 ` Manfred Spraul
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20051227163059.GA2381@sgi.com \
--to=steiner@sgi.com \
--cc=akpm@osdl.org \
--cc=linux-ia64@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.