Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=34bbd704051c9d053d69e90569a3a2365f4c7b50 Commit: 34bbd704051c9d053d69e90569a3a2365f4c7b50 Parent: 48dba8ab9b93c3b6b57946bd45ae013402b0b054 Author: Oleg Nesterov <[EMAIL PROTECTED]> AuthorDate: Wed Feb 28 20:13:49 2007 -0800 Committer: Linus Torvalds <[EMAIL PROTECTED]> CommitDate: Thu Mar 1 14:53:39 2007 -0800
[PATCH] adapt page_lock_anon_vma() to PREEMPT_RCU page_lock_anon_vma() uses spin_lock() to block RCU. This doesn't work with PREEMPT_RCU, we have to do rcu_read_lock() explicitely. Otherwise, it is theoretically possible that slab returns anon_vma's memory to the system before we do spin_unlock(&anon_vma->lock). [ Hugh points out that this only matters for PREEMPT_RCU, which isn't merged yet, and may never be. Regardless, this patch is conceptually the right thing to do, even if it doesn't matter at this point. - Linus ] Signed-off-by: Oleg Nesterov <[EMAIL PROTECTED]> Cc: Paul McKenney <[EMAIL PROTECTED]> Cc: Nick Piggin <[EMAIL PROTECTED]> Cc: Christoph Lameter <[EMAIL PROTECTED]> Acked-by: Hugh Dickins <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]> --- mm/rmap.c | 17 +++++++++++++---- 1 files changed, 13 insertions(+), 4 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 669acb2..22ed3f7 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -183,7 +183,7 @@ void __init anon_vma_init(void) */ static struct anon_vma *page_lock_anon_vma(struct page *page) { - struct anon_vma *anon_vma = NULL; + struct anon_vma *anon_vma; unsigned long anon_mapping; rcu_read_lock(); @@ -195,9 +195,16 @@ static struct anon_vma *page_lock_anon_vma(struct page *page) anon_vma = (struct anon_vma *) (anon_mapping - PAGE_MAPPING_ANON); spin_lock(&anon_vma->lock); + return anon_vma; out: rcu_read_unlock(); - return anon_vma; + return NULL; +} + +static void page_unlock_anon_vma(struct anon_vma *anon_vma) +{ + spin_unlock(&anon_vma->lock); + rcu_read_unlock(); } /* @@ -333,7 +340,8 @@ static int page_referenced_anon(struct page *page) if (!mapcount) break; } - spin_unlock(&anon_vma->lock); + + page_unlock_anon_vma(anon_vma); return referenced; } @@ -802,7 +810,8 @@ static int try_to_unmap_anon(struct page *page, int migration) if (ret == SWAP_FAIL || !page_mapped(page)) break; } - spin_unlock(&anon_vma->lock); + + page_unlock_anon_vma(anon_vma); return ret; } - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html