summaryrefslogtreecommitdiff
path: root/include/linux/list.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.osdl.org>2003-12-11 22:20:08 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2003-12-11 22:20:08 -0800
commita2c72fae694277071dcbab33dfb7f88af5e54954 (patch)
treeb355440cdca67decc3db5fffb042b34e29dcecbf /include/linux/list.h
parent8cc86c08950c41dc88006534c3508d03cf0dfe39 (diff)
Fix subtle bug in "finish_wait()", which can cause kernel stack
corruption on SMP because of another CPU still accessing a waitqueue even after it was de-allocated. Use a careful version of the list emptiness check to make sure we don't de-allocate the stack frame before the waitqueue is all done.
Diffstat (limited to 'include/linux/list.h')
-rw-r--r--include/linux/list.h12
1 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/list.h b/include/linux/list.h
index b7d383e6a312..0835011b0ffb 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -208,6 +208,18 @@ static inline int list_empty(const struct list_head *head)
return head->next == head;
}
+/**
+ * list_empty_careful - tests whether a list is
+ * empty _and_ checks that no other CPU might be
+ * in the process of still modifying either member
+ * @head: the list to test.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+ struct list_head *next = head->next;
+ return (next == head) && (next == head->prev);
+}
+
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{