From 7f803438578b17b402ace16e3c39489fcf49e046 Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Thu, 13 Jan 2011 15:47:21 -0800 Subject: [PATCH] --- yaml --- r: 230815 b: refs/heads/master c: 29c1f677d424e8c5683a837fc4f03fc9f19201d7 h: refs/heads/master i: 230813: 48a469b20229e7fe7ed5ee7c6ac71b7945ec99d6 230811: aa1a7fa2a36402f177d940ee709369172757e56d 230807: 6d2bf2e9186386e382e6d306aad02a47357bb6bc 230799: 566a5d333ee1c8c54ecac09d3f346c7bba31ac53 230783: 0bb77c67a20369c0d109e35622430e93746bc565 v: v3 --- [refs] | 2 +- trunk/include/linux/radix-tree.h | 16 ++++++++++++++++ trunk/mm/migrate.c | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 1fbc6b8cc5cd..a78c0b8a46f0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 22e5c47ee238abe636655c3862ed28d6eb084ad4 +refs/heads/master: 29c1f677d424e8c5683a837fc4f03fc9f19201d7 diff --git a/trunk/include/linux/radix-tree.h b/trunk/include/linux/radix-tree.h index ab2baa5c4884..23241c2fecce 100644 --- a/trunk/include/linux/radix-tree.h +++ b/trunk/include/linux/radix-tree.h @@ -145,6 +145,22 @@ static inline void *radix_tree_deref_slot(void **pslot) return rcu_dereference(*pslot); } +/** + * radix_tree_deref_slot_protected - dereference a slot without RCU lock but with tree lock held + * @pslot: pointer to slot, returned by radix_tree_lookup_slot + * Returns: item that was stored in that slot with any direct pointer flag + * removed. + * + * Similar to radix_tree_deref_slot but only used during migration when a pages + * mapping is being moved. The caller does not hold the RCU read lock but it + * must hold the tree lock to prevent parallel updates. + */ +static inline void *radix_tree_deref_slot_protected(void **pslot, + spinlock_t *treelock) +{ + return rcu_dereference_protected(*pslot, lockdep_is_held(treelock)); +} + /** * radix_tree_deref_retry - check radix_tree_deref_slot * @arg: pointer returned by radix_tree_deref_slot diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 1a531b760b3b..89a6bc8cd307 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -248,7 +248,7 @@ static int migrate_page_move_mapping(struct address_space *mapping, expected_count = 2 + page_has_private(page); if (page_count(page) != expected_count || - (struct page *)radix_tree_deref_slot(pslot) != page) { + radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) { spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; } @@ -320,7 +320,7 @@ int migrate_huge_page_move_mapping(struct address_space *mapping, expected_count = 2 + page_has_private(page); if (page_count(page) != expected_count || - (struct page *)radix_tree_deref_slot(pslot) != page) { + radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) { spin_unlock_irq(&mapping->tree_lock); return -EAGAIN; }