diff options
author | Nick Piggin <piggin@cyberone.com.au> | 2006-04-10 11:21:48 +1000 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-10 10:16:37 -0700 |
commit | 676165a8af7167f488abdcce6851a9bc36e83254 (patch) | |
tree | a9b2b8dc155b48ce073b5ada31f2ac0694118e69 /include/linux/mm.h | |
parent | c3a9d6541f84ac3ff566982d08389b87c1c36b4e (diff) | |
download | linux-676165a8af7167f488abdcce6851a9bc36e83254.tar.gz linux-676165a8af7167f488abdcce6851a9bc36e83254.tar.bz2 linux-676165a8af7167f488abdcce6851a9bc36e83254.zip |
[PATCH] Fix buddy list race that could lead to page lru list corruptions
Rohit found an obscure bug causing buddy list corruption.
page_is_buddy is using a non-atomic test (PagePrivate && page_count == 0)
to determine whether or not a free page's buddy is itself free and in the
buddy lists.
Each of the conjuncts may be true at different times due to unrelated
conditions, so the non-atomic page_is_buddy test may find each conjunct to
be true even if they were not both true at the same time (ie. the page was
not on the buddy lists).
Signed-off-by: Martin Bligh <mbligh@google.com>
Signed-off-by: Rohit Seth <rohitseth@google.com>
Signed-off-by: Nick Piggin <npiggin@suse.de>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/mm.h')
-rw-r--r-- | include/linux/mm.h | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 6aa016f1d3ae..1154684209a4 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -229,10 +229,9 @@ struct page { unsigned long private; /* Mapping-private opaque data: * usually used for buffer_heads * if PagePrivate set; used for - * swp_entry_t if PageSwapCache. - * When page is free, this + * swp_entry_t if PageSwapCache; * indicates order in the buddy - * system. + * system if PG_buddy is set. */ struct address_space *mapping; /* If low bit clear, points to * inode address_space, or NULL. |