lkml.org 
[lkml]   [2001]   [Apr]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: [PATCH][RFC] appling preasure to icache and dcache
Date
Hi,

The patch in the last message was scrambled. The last two lines
belong to the previous fragment. Here is the correct beast.

Ed Tomlinson <tomlins@cam.org

---
diff -u -r --exclude-from=ex.txt linux.ac28/mm/page_alloc.c linux/mm/page_alloc.c
--- linux.ac28/mm/page_alloc.c Sun Apr 1 18:52:22 2001
+++ linux/mm/page_alloc.c Mon Apr 2 07:54:05 2001
@@ -138,11 +138,9 @@

/*
* We don't want to protect this variable from race conditions
- * since it's nothing important, but we do want to make sure
- * it never gets negative.
+ * since it's nothing important.
*/
- if (memory_pressure > NR_CPUS)
- memory_pressure--;
+ inactivate_pressure++;
}

#define MARK_USED(index, order, area) \
diff -u -r --exclude-from=ex.txt linux.ac28/mm/swap.c linux/mm/swap.c
--- linux.ac28/mm/swap.c Mon Jan 22 16:30:21 2001
+++ linux/mm/swap.c Thu Mar 29 11:37:47 2001
@@ -47,10 +47,12 @@
* many inactive pages we should have.
*
* In reclaim_page and __alloc_pages: memory_pressure++
- * In __free_pages_ok: memory_pressure--
+ * In __free_pages_ok: inactivate_pressure++
+ * In invalidate_pages_scan: inactivate_pressure++
* In recalculate_vm_stats the value is decayed (once a second)
*/
int memory_pressure;
+int inactivate_pressure;

/* We track the number of pages currently being asynchronously swapped
out, so that we don't try to swap TOO many pages out at once */
@@ -287,6 +289,7 @@
* memory_pressure.
*/
memory_pressure -= (memory_pressure >> INACTIVE_SHIFT);
+ inactivate_pressure -= (inactivate_pressure >> INACTIVE_SHIFT);
}

/*
diff -u -r --exclude-from=ex.txt linux.ac28/mm/vmscan.c linux/mm/vmscan.c
--- linux.ac28/mm/vmscan.c Sun Apr 1 18:52:22 2001
+++ linux/mm/vmscan.c Mon Apr 2 07:42:55 2001
@@ -759,6 +791,8 @@
}
spin_unlock(&pagemap_lru_lock);

+ inactivate_pressure += nr_deactivated;
+
return nr_deactivated;
}

@@ -937,6 +971,76 @@
return ret;
}

+/*
+ * Try to shrink the dcache if either its size or free space
+ * has grown, and it looks like we might get the required pages.
+ * This function would simplify if the caches tracked how
+ * many _pages_ were freeable.
+ */
+int try_shrinking_dcache(int goal, unsigned int gfp_mask)
+{
+
+ /* base - projects the threshold above which we can free pages */
+
+ static int base, free = 0;
+ int pages, old, ret;
+
+ old = free; /* save old free space size */
+
+ pages = (dentry_stat.nr_dentry * sizeof(struct dentry)) >> PAGE_SHIFT;
+ free = (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
+
+ if (base > pages) /* If the cache shrunk reset base, The cache
+ base = pages; * growing applies preasure as does expanding
+ if (free > old) * free space - even if later shrinks */
+ base -= (base>free-old) ? free-old : base;
+
+ /* try free pages... Note that the using inactive_pressure _is_
+ * racy. It does not matter, a bad guess will not hurt us.
+ * Testing free here does not work effectivily.
+ */
+
+ if (pages-base >= goal) {
+ ret = inactivate_pressure;
+ shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
+ ret = inactivate_pressure - ret;
+ base += (!ret) ? pages-base : (ret>goal) ? ret : goal;
+ } else
+ ret = 0;
+
+ return ret;
+}
+
+/*
+ * Same logic as above but for the icache.
+ */
+int try_shrinking_icache(int goal, unsigned int gfp_mask)
+{
+ static int base, free = 0;
+ int pages, old, ret;
+
+ old = free;
+
+ pages = (inodes_stat.nr_inodes * sizeof(struct inode)) >> PAGE_SHIFT;
+ free = (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+
+ if (base > pages)
+ base = pages;
+ if (free > old)
+ base -= (base>free-old) ? free-old : base;
+
+ if (pages-base >= goal) {
+ ret = inactivate_pressure;
+ shrink_icache_memory(DEF_PRIORITY, gfp_mask);
+ ret = inactivate_pressure - ret;
+ base += (!ret) ? pages-base : (ret>goal) ? ret : goal;
+ } else
+ ret = 0;
+
+ return ret;
+}
+
+
DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
DECLARE_WAIT_QUEUE_HEAD(kswapd_done);
struct task_struct *kswapd_task;
@@ -984,18 +1088,28 @@
*/
for (;;) {
static int recalc = 0;
+ int delta = 0;

/* If needed, try to free some memory. */
if (inactive_shortage() || free_shortage())
do_try_to_free_pages(GFP_KSWAPD, 0);

/*
- * Do some (very minimal) background scanning. This
- * will scan all pages on the active list once
- * every minute. This clears old referenced bits
- * and moves unused pages to the inactive list.
+ * Try to keep the rate of pages inactivations
+ * similar to the rate of pages allocations. This
+ * also perform background page aging, but only
+ * when there is preasure on the vm. We get the
+ * pages from the dcache and icache if its likely
+ * there are enought freeable pages there.
*/
- refill_inactive_scan(DEF_PRIORITY, 0);
+ delta = (memory_pressure >> INACTIVE_SHIFT) \
+ - (inactivate_pressure >> INACTIVE_SHIFT);
+ if (delta > 0)
+ delta -= try_shrinking_dcache(delta,GFP_KSWAPD);
+ if (delta > 0)
+ delta -= try_shrinking_icache(delta,GFP_KSWAPD);
+ if (delta > 0)
+ refill_inactive_scan(DEF_PRIORITY, delta);

/* Once a second, recalculate some VM stats. */
if (time_after(jiffies, recalc + HZ)) {
--- linux.ac28/include/linux/swap.h Sun Apr 1 18:52:22 2001
+++ linux/include/linux/swap.h Thu Mar 29 11:31:09 2001
@@ -102,6 +102,7 @@

/* linux/mm/swap.c */
extern int memory_pressure;
+extern int inactivate_pressure;
extern void age_page_up(struct page *);
extern void age_page_up_nolock(struct page *);
extern void age_page_down(struct page *);
---
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 13:22    [W:0.022 / U:0.512 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site