--- fs/hugetlbfs/inode.c | 8 +++++--- include/linux/hugetlb.h | 3 ++- include/linux/mmu_notifier.h | 6 +++--- mm/hugetlb.c | 6 +++--- mm/memory.c | 3 ++- 5 files changed, 15 insertions(+), 11 deletions(-) Index: linux-2.6/include/linux/hugetlb.h =================================================================== --- linux-2.6.orig/include/linux/hugetlb.h 2008-01-25 18:55:29.000000000 -0800 +++ linux-2.6/include/linux/hugetlb.h 2008-01-25 18:55:58.000000000 -0800 @@ -21,7 +21,8 @@ int hugetlb_treat_movable_handler(struct int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *); int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int, int); void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); -void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long); +void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, + unsigned long, spinlock_t *); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); int hugetlb_report_meminfo(char *); int hugetlb_report_node_meminfo(int, char *); Index: linux-2.6/mm/hugetlb.c =================================================================== --- linux-2.6.orig/mm/hugetlb.c 2008-01-25 18:53:40.000000000 -0800 +++ linux-2.6/mm/hugetlb.c 2008-01-25 18:55:13.000000000 -0800 @@ -725,7 +725,7 @@ nomem: } void __unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) + unsigned long end, spinlock_t *lock) { struct mm_struct *mm = vma->vm_mm; unsigned long address; @@ -764,7 +764,7 @@ void __unmap_hugepage_range(struct vm_ar } spin_unlock(&mm->page_table_lock); flush_tlb_range(vma, start, end); - mmu_notifier(invalidate_range, mm, start, end, &inodep); + mmu_notifier(invalidate_range, mm, start, end, &lockp); list_for_each_entry_safe(page, tmp, &page_list, lru) { list_del(&page->lru); put_page(page); @@ -784,7 +784,7 @@ void unmap_hugepage_range(struct vm_area */ if (vma->vm_file) { spin_lock(&vma->vm_file->f_mapping->i_mmap_lock); - __unmap_hugepage_range(vma, start, end); + __unmap_hugepage_range(vma, start, end, &vma->vm_file->f_mapping->i_mmap_lock); spin_unlock(&vma->vm_file->f_mapping->i_mmap_lock); } } Index: linux-2.6/fs/hugetlbfs/inode.c =================================================================== --- linux-2.6.orig/fs/hugetlbfs/inode.c 2008-01-25 18:57:05.000000000 -0800 +++ linux-2.6/fs/hugetlbfs/inode.c 2008-01-25 18:59:04.000000000 -0800 @@ -421,7 +421,8 @@ static void hugetlbfs_drop_inode(struct } static inline void -hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff) +hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff, + spinlock_t *lockp) { struct vm_area_struct *vma; struct prio_tree_iter iter; @@ -441,7 +442,7 @@ hugetlb_vmtruncate_list(struct prio_tree v_offset = 0; __unmap_hugepage_range(vma, - vma->vm_start + v_offset, vma->vm_end); + vma->vm_start + v_offset, vma->vm_end, &lockp); } } @@ -456,7 +457,8 @@ static int hugetlb_vmtruncate(struct ino i_size_write(inode, offset); spin_lock(&mapping->i_mmap_lock); if (!prio_tree_empty(&mapping->i_mmap)) - hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); + hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff, + &mapping->i_mmap_lock); spin_unlock(&mapping->i_mmap_lock); truncate_hugepages(inode, offset); return 0; Index: linux-2.6/include/linux/mmu_notifier.h =================================================================== --- linux-2.6.orig/include/linux/mmu_notifier.h 2008-01-25 18:59:12.000000000 -0800 +++ linux-2.6/include/linux/mmu_notifier.h 2008-01-25 18:59:59.000000000 -0800 @@ -63,13 +63,13 @@ struct mmu_notifier_ops { unsigned long address); /* - * If zap_details are passed then we may be holding the - * i_mmmap_lock in the mapping. + * If lockp is != NULL then we are holding the indicated + * spinlock. */ void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long start, unsigned long end, - struct zap_details *z); + spinlock_t *lockp); }; struct mmu_rmap_notifier_ops; Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c 2008-01-25 18:56:04.000000000 -0800 +++ linux-2.6/mm/memory.c 2008-01-25 19:03:24.000000000 -0800 @@ -892,7 +892,8 @@ unsigned long zap_page_range(struct vm_a end = unmap_vmas(&tlb, vma, address, end, &nr_accounted, details); if (tlb) tlb_finish_mmu(tlb, address, end); - mmu_notifier(invalidate_range, mm, address, end, details); + mmu_notifier(invalidate_range, mm, address, end, + (details ? details->i_mmap_lock : NULL)); return end; }