diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2003-12-11 22:20:08 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-12-11 22:20:08 -0800 |
| commit | a2c72fae694277071dcbab33dfb7f88af5e54954 (patch) | |
| tree | b355440cdca67decc3db5fffb042b34e29dcecbf /include/linux/list.h | |
| parent | 8cc86c08950c41dc88006534c3508d03cf0dfe39 (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.h | 12 |
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) { |
