patch-2.4.11-dontuse linux/mm/vmscan.c
Next file: linux/net/appletalk/aarp.c
Previous file: linux/mm/swapfile.c
Back to the patch index
Back to the overall index
- Lines: 145
- Date:
Sun Oct 7 17:18:31 2001
- Orig file:
v2.4.10/linux/mm/vmscan.c
- Orig date:
Sun Sep 23 11:41:01 2001
diff -u --recursive --new-file v2.4.10/linux/mm/vmscan.c linux/mm/vmscan.c
@@ -125,18 +125,20 @@
* we have the swap cache set up to associate the
* page with that swap entry.
*/
- swap_list_lock();
- entry = get_swap_page();
- if (entry.val) {
+ for (;;) {
+ entry = get_swap_page();
+ if (!entry.val)
+ break;
/* Add it to the swap cache and mark it dirty */
- add_to_swap_cache(page, entry);
- swap_list_unlock();
- set_page_dirty(page);
- goto set_swap_pte;
+ if (add_to_swap_cache(page, entry) == 0) {
+ set_page_dirty(page);
+ goto set_swap_pte;
+ }
+ /* Raced with "speculative" read_swap_cache_async */
+ swap_free(entry);
}
/* No swap space left */
- swap_list_unlock();
set_pte(page_table, pte);
UnlockPage(page);
return 0;
@@ -332,7 +334,6 @@
spin_lock(&pagemap_lru_lock);
while (max_scan && (entry = inactive_list.prev) != &inactive_list) {
struct page * page;
- swp_entry_t swap;
if (unlikely(current->need_resched)) {
spin_unlock(&pagemap_lru_lock);
@@ -407,12 +408,6 @@
if (try_to_free_buffers(page, gfp_mask)) {
if (!page->mapping) {
/*
- * Account we successfully freed a page
- * of buffer cache.
- */
- atomic_dec(&buffermem_pages);
-
- /*
* We must not allow an anon page
* with no buffers to be visible on
* the LRU, so we unlock the page after
@@ -472,23 +467,17 @@
/* point of no return */
if (likely(!PageSwapCache(page))) {
- swap.val = 0;
__remove_inode_page(page);
+ spin_unlock(&pagecache_lock);
} else {
+ swp_entry_t swap;
swap.val = page->index;
__delete_from_swap_cache(page);
- }
- spin_unlock(&pagecache_lock);
-
- __lru_cache_del(page);
-
- if (unlikely(swap.val != 0)) {
- /* must drop lru lock if getting swap_list lock */
- spin_unlock(&pagemap_lru_lock);
+ spin_unlock(&pagecache_lock);
swap_free(swap);
- spin_lock(&pagemap_lru_lock);
}
+ __lru_cache_del(page);
UnlockPage(page);
/* effectively free the page here */
@@ -536,33 +525,40 @@
static int FASTCALL(shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages));
static int shrink_caches(int priority, zone_t * classzone, unsigned int gfp_mask, int nr_pages)
{
- int max_scan = nr_inactive_pages / priority;
+ int max_scan;
+ int chunk_size = nr_pages;
+ unsigned long ratio;
nr_pages -= kmem_cache_reap(gfp_mask);
if (nr_pages <= 0)
return 0;
- /* Do we want to age the active list? */
- if (nr_inactive_pages < nr_active_pages*2)
- refill_inactive(nr_pages);
-
+ nr_pages = chunk_size;
+ /* try to keep the active list 2/3 of the size of the cache */
+ ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
+ refill_inactive(ratio);
+
+ max_scan = nr_inactive_pages / priority;
nr_pages = shrink_cache(nr_pages, max_scan, classzone, gfp_mask);
if (nr_pages <= 0)
return 0;
shrink_dcache_memory(priority, gfp_mask);
shrink_icache_memory(priority, gfp_mask);
+#ifdef CONFIG_QUOTA
+ shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+#endif
return nr_pages;
}
int try_to_free_pages(zone_t * classzone, unsigned int gfp_mask, unsigned int order)
{
- int priority = DEF_PRIORITY;
int ret = 0;
+ int priority = DEF_PRIORITY;
+ int nr_pages = SWAP_CLUSTER_MAX;
do {
- int nr_pages = SWAP_CLUSTER_MAX;
nr_pages = shrink_caches(priority, classzone, gfp_mask, nr_pages);
if (nr_pages <= 0)
return 1;
@@ -602,7 +598,7 @@
if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
zone->need_balance = 0;
__set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ*5);
+ schedule_timeout(HZ);
continue;
}
if (check_classzone_need_balance(zone))
@@ -625,6 +621,9 @@
do
need_more_balance |= kswapd_balance_pgdat(pgdat);
while ((pgdat = pgdat->node_next));
+ if (need_more_balance && out_of_memory()) {
+ oom_kill();
+ }
} while (need_more_balance);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)