diff -urN 2.4.0-test5/mm/filemap.c msync-smp-race/mm/filemap.c --- 2.4.0-test5/mm/filemap.c Fri Jul 28 07:24:15 2000 +++ msync-smp-race/mm/filemap.c Tue Aug 1 21:20:24 2000 @@ -1557,12 +1557,14 @@ pte_t pte = *ptep; struct page *page; int error; + spinlock_t * page_table_lock = &vma->vm_mm->page_table_lock; + spin_lock(page_table_lock); if (!(flags & MS_INVALIDATE)) { if (!pte_present(pte)) - return 0; + goto out_unlock; if (!pte_dirty(pte)) - return 0; + goto out_unlock; flush_page_to_ram(pte_page(pte)); flush_cache_page(vma, address); set_pte(ptep, pte_mkclean(pte)); @@ -1571,20 +1573,22 @@ page_cache_get(page); } else { if (pte_none(pte)) - return 0; + goto out_unlock; flush_cache_page(vma, address); pte_clear(ptep); flush_tlb_page(vma, address); if (!pte_present(pte)) { swap_free(pte_to_swp_entry(pte)); - return 0; + goto out_unlock; } page = pte_page(pte); if (!pte_dirty(pte) || flags == MS_INVALIDATE) { + spin_unlock(page_table_lock); page_cache_free(page); return 0; } } + spin_unlock(page_table_lock); pgoff = (address - vma->vm_start) >> PAGE_CACHE_SHIFT; pgoff += vma->vm_pgoff; if (page->index != pgoff) { @@ -1596,6 +1600,10 @@ UnlockPage(page); page_cache_free(page); return error; + + out_unlock: + spin_unlock(page_table_lock); + return 0; } static inline int filemap_sync_pte_range(pmd_t * pmd,