--- zzzz-none-000/linux-2.4.17/mm/filemap.c 2001-12-21 17:42:04.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/mm/filemap.c 2004-11-24 13:22:34.000000000 +0000 @@ -25,6 +25,8 @@ #include #include +#include + #include #include #include @@ -296,6 +298,7 @@ page_cache_release(page); + /* we hit this with lock depth of 1 or 2 */ if (current->need_resched) { __set_current_state(TASK_RUNNING); schedule(); @@ -406,6 +409,8 @@ } page_cache_release(page); + + debug_lock_break(551); if (current->need_resched) { __set_current_state(TASK_RUNNING); schedule(); @@ -594,12 +599,16 @@ list_del(&page->list); list_add(&page->list, &mapping->locked_pages); - if (!PageDirty(page)) - continue; - page_cache_get(page); spin_unlock(&pagecache_lock); + /* BKL is held ... */ + debug_lock_break(1); + conditional_schedule(); + + if (!PageDirty(page)) + goto clean; + lock_page(page); if (PageDirty(page)) { @@ -607,7 +616,7 @@ writepage(page); } else UnlockPage(page); - +clean: page_cache_release(page); spin_lock(&pagecache_lock); } @@ -623,14 +632,28 @@ */ void filemap_fdatawait(struct address_space * mapping) { + DEFINE_LOCK_COUNT(); + spin_lock(&pagecache_lock); +restart: while (!list_empty(&mapping->locked_pages)) { struct page *page = list_entry(mapping->locked_pages.next, struct page, list); list_del(&page->list); list_add(&page->list, &mapping->clean_pages); - + + if (TEST_LOCK_COUNT(32)) { + RESET_LOCK_COUNT(); + debug_lock_break(2); + if (conditional_schedule_needed()) { + page_cache_get(page); + break_spin_lock_and_resched(&pagecache_lock); + page_cache_release(page); + goto restart; + } + } + if (!PageLocked(page)) continue; @@ -787,10 +810,12 @@ set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!PageLocked(page)) break; + TRACE_MEMORY(TRACE_EV_MEMORY_PAGE_WAIT_START, 0); sync_page(page); schedule(); } while (PageLocked(page)); tsk->state = TASK_RUNNING; + TRACE_MEMORY(TRACE_EV_MEMORY_PAGE_WAIT_END, 0); remove_wait_queue(&page->wait, &wait); } @@ -894,6 +919,7 @@ * the hash-list needs a held write-lock. */ repeat: + break_spin_lock(&pagecache_lock); page = __find_page_nolock(mapping, offset, hash); if (page) { page_cache_get(page); @@ -941,7 +967,6 @@ spin_unlock(&pagecache_lock); if (!page) { struct page *newpage = alloc_page(gfp_mask); - page = NULL; if (newpage) { spin_lock(&pagecache_lock); page = __find_lock_page_helper(mapping, index, *hash); @@ -2055,6 +2080,8 @@ address += PAGE_SIZE; pte++; } while (address && (address < end)); + debug_lock_break(1); + break_spin_lock(&vma->vm_mm->page_table_lock); return error; } @@ -2085,6 +2112,9 @@ address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address && (address < end)); + + debug_lock_break(1); + break_spin_lock(&vma->vm_mm->page_table_lock); return error; } @@ -2135,6 +2165,7 @@ return -ENOEXEC; UPDATE_ATIME(inode); vma->vm_ops = &generic_file_vm_ops; + vma->vm_flags &= ~VM_IO; return 0; } @@ -2443,7 +2474,7 @@ if (vma->vm_flags & VM_LOCKED) return -EINVAL; - zap_page_range(vma->vm_mm, start, end - start); + zap_page_range(vma->vm_mm, start, end - start, ZPR_PARTITION); return 0; }