From: Dave McCracken <dmccr@us.ibm.com>

Paul McKenney pointed out that reading the truncate sequence number in
do_no_page might not be entirely safe if the ->nopage callout takes no
locks.  The simple solution is to move the read before the unlock of
page_table_lock.  Here's a patch that does it.



 mm/memory.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff -puN mm/memory.c~truncate-pagefault-race-fix-fix mm/memory.c
--- 25/mm/memory.c~truncate-pagefault-race-fix-fix	2003-07-02 22:12:25.000000000 -0700
+++ 25-akpm/mm/memory.c	2003-07-02 22:12:25.000000000 -0700
@@ -1390,11 +1390,11 @@ do_no_page(struct mm_struct *mm, struct 
 		return do_anonymous_page(mm, vma, page_table,
 					pmd, write_access, address);
 	pte_unmap(page_table);
-	spin_unlock(&mm->page_table_lock);
 
 	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
-retry:
 	sequence = atomic_read(&mapping->truncate_count);
+	spin_unlock(&mm->page_table_lock);
+retry:
 	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
 
 	/* no page was available -- either SIGBUS or OOM */
@@ -1429,6 +1429,7 @@ retry:
 	 * retry getting the page.
 	 */
 	if (unlikely(sequence != atomic_read(&mapping->truncate_count))) {
+		sequence = atomic_read(&mapping->truncate_count);
 		spin_unlock(&mm->page_table_lock);
 		page_cache_release(new_page);
 		goto retry;

_