patch-2.4.0-test12 linux/mm/vmscan.c
Next file: linux/net/802/fddi.c
Previous file: linux/mm/vmalloc.c
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Mon Dec 4 15:36:55 2000
- Orig file:
v2.4.0-test11/linux/mm/vmscan.c
- Orig date:
Sun Nov 19 18:44:23 2000
diff -u --recursive --new-file v2.4.0-test11/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -91,6 +91,9 @@
*/
if (PageSwapCache(page)) {
entry.val = page->index;
+ if (pte_dirty(pte))
+ SetPageDirty(page);
+set_swap_pte:
swap_duplicate(entry);
set_pte(page_table, swp_entry_to_pte(entry));
drop_pte:
@@ -99,7 +102,8 @@
flush_tlb_page(vma, address);
deactivate_page(page);
page_cache_release(page);
- goto out_failed;
+out_failed:
+ return 0;
}
/*
@@ -166,13 +170,13 @@
flush_tlb_page(vma, address);
spin_unlock(&mm->page_table_lock);
error = swapout(page, file);
- UnlockPage(page);
if (file) fput(file);
- if (!error)
- goto out_free_success;
+ if (error < 0)
+ goto out_unlock_restore;
+ UnlockPage(page);
deactivate_page(page);
page_cache_release(page);
- return error;
+ return 1; /* We released page_table_lock */
}
/*
@@ -185,33 +189,11 @@
if (!entry.val)
goto out_unlock_restore; /* No swap space left */
- /* Make sure to flush the TLB _before_ we start copying things.. */
- flush_tlb_page(vma, address);
- if (!(page = prepare_highmem_swapout(page)))
- goto out_swap_free;
-
- swap_duplicate(entry); /* One for the process, one for the swap cache */
-
- /* Add it to the swap cache */
+ /* Add it to the swap cache and mark it dirty */
add_to_swap_cache(page, entry);
+ SetPageDirty(page);
+ goto set_swap_pte;
- /* Put the swap entry into the pte after the page is in swapcache */
- mm->rss--;
- set_pte(page_table, swp_entry_to_pte(entry));
- spin_unlock(&mm->page_table_lock);
-
- /* OK, do a physical asynchronous write to swap. */
- rw_swap_page(WRITE, page, 0);
- deactivate_page(page);
-
-out_free_success:
- page_cache_release(page);
- return 1;
-out_swap_free:
- set_pte(page_table, pte);
- swap_free(entry);
-out_failed:
- return 0;
out_unlock_restore:
set_pte(page_table, pte);
UnlockPage(page);
@@ -501,7 +483,7 @@
continue;
}
- /* The page is dirty, or locked, move to inactive_diry list. */
+ /* The page is dirty, or locked, move to inactive_dirty list. */
if (page->buffers || TryLockPage(page)) {
del_page_from_inactive_clean_list(page);
add_page_to_inactive_dirty_list(page);
@@ -616,6 +598,36 @@
}
/*
+ * Dirty swap-cache page? Write it out if
+ * last copy..
+ */
+ if (PageDirty(page)) {
+ int (*writepage)(struct page *) = page->mapping->a_ops->writepage;
+ if (!writepage)
+ goto page_active;
+
+ /* Can't start IO? Move it to the back of the list */
+ if (!can_get_io_locks) {
+ list_del(page_lru);
+ list_add(page_lru, &inactive_dirty_list);
+ UnlockPage(page);
+ continue;
+ }
+
+ /* OK, do a physical asynchronous write to swap. */
+ ClearPageDirty(page);
+ page_cache_get(page);
+ spin_unlock(&pagemap_lru_lock);
+
+ writepage(page);
+ page_cache_release(page);
+
+ /* And re-start the thing.. */
+ spin_lock(&pagemap_lru_lock);
+ continue;
+ }
+
+ /*
* If the page has buffers, try to free the buffer mappings
* associated with this page. If we succeed we either free
* the page (in case it was a buffercache only page) or we
@@ -701,6 +713,7 @@
UnlockPage(page);
cleaned_pages++;
} else {
+page_active:
/*
* OK, we don't know what to do with the page.
* It's no use keeping it here, so we move it to
@@ -924,13 +937,6 @@
*/
shrink_dcache_memory(priority, gfp_mask);
shrink_icache_memory(priority, gfp_mask);
-
- /* Try to get rid of some shared memory pages.. */
- while (shm_swap(priority, gfp_mask)) {
- made_progress = 1;
- if (--count <= 0)
- goto done;
- }
/*
* Then, try to page stuff out..
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)