
From: Hugh Dickins <hugh@veritas.com>

Sorry, my premature optimizations (trying to pass down NULL zap_details except
when needed) have caught you out doubly: unmap_mapping_range_list was NULLing
the details even though atomic was set; and if it hadn't, then zap_pte_range
would have missed free_swap_and_cache and pte_clear when pte not present. 
Moved the optimization into zap_pte_range itself.  Plus massive documentation
update.


---

 25-akpm/Documentation/vm/locking |    2 +-
 25-akpm/mm/memory.c              |    5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff -puN Documentation/vm/locking~i_shared_lock-fix-1 Documentation/vm/locking
--- 25/Documentation/vm/locking~i_shared_lock-fix-1	Wed Apr 21 14:21:04 2004
+++ 25-akpm/Documentation/vm/locking	Wed Apr 21 14:21:04 2004
@@ -66,7 +66,7 @@ in some cases it is not really needed. E
 expand_stack(), it is hard to come up with a destructive scenario without 
 having the vmlist protection in this case.
 
-The page_table_lock nests with the inode i_shared_sem and the kmem cache
+The page_table_lock nests with the inode i_shared_lock and the kmem cache
 c_spinlock spinlocks.  This is okay, since the kmem code asks for pages after
 dropping c_spinlock.  The page_table_lock also nests with pagecache_lock and
 pagemap_lru_lock spinlocks, and no code asks for memory with these locks
diff -puN mm/memory.c~i_shared_lock-fix-1 mm/memory.c
--- 25/mm/memory.c~i_shared_lock-fix-1	Wed Apr 21 14:21:04 2004
+++ 25-akpm/mm/memory.c	Wed Apr 21 14:21:04 2004
@@ -365,6 +365,8 @@ static void zap_pte_range(struct mmu_gat
 	if (offset + size > PMD_SIZE)
 		size = PMD_SIZE - offset;
 	size &= PAGE_MASK;
+	if (details && !details->check_mapping && !details->nonlinear_vma)
+		details = NULL;
 	for (offset=0; offset < size; ptep++, offset += PAGE_SIZE) {
 		pte_t pte = *ptep;
 		if (pte_none(pte))
@@ -1132,8 +1134,7 @@ static void unmap_mapping_range_list(str
 			zea = vea;
 		zap_page_range(vma,
 			((zba - vba) << PAGE_SHIFT) + vma->vm_start,
-			(zea - zba + 1) << PAGE_SHIFT,
-			details->check_mapping? details: NULL);
+			(zea - zba + 1) << PAGE_SHIFT, details);
 	}
 }
 

_
