I believe it make no sense to rotate the LRU of the dcache and that I
should simply shrink things in LRU order. Avoiding select_dcache will also
avoid a pass on the dcache lru.
If something we may leather add a reference bit to the i/dcache exactly as
we do with the page-LRU and such bit will be efficient handled and will
give us a real information of the LRU objects (and not only a heuristic
based on the number of pages queued).
Here it is a patch against my inode-dynamic patch that can be found here:
ftp://ftp.suse.com/pub/people/andrea/kernel-patches/my-2.3.18ac9/inode-dynamic-4
diff -urN 2.3.18ac9-inode/fs/dcache.c 2.3.18ac9-select_dcache/fs/dcache.c
--- 2.3.18ac9-inode/fs/dcache.c Wed Sep 29 16:04:39 1999
+++ 2.3.18ac9-select_dcache/fs/dcache.c Wed Sep 29 16:08:28 1999
@@ -196,72 +196,6 @@
}
/*
- * Select less valuable dentries to be pruned when we need
- * inodes or memory. The selected dentries are moved to the
- * old end of the list where prune_dcache() can find them.
- *
- * Negative dentries are included in the selection so that
- * they don't accumulate at the end of the list. The count
- * returned is the total number of dentries selected, which
- * may be much larger than the requested number of inodes.
- */
-int select_dcache(int inode_count, int page_count)
-{
- struct list_head *next, *tail = &dentry_unused;
- int found = 0;
- int depth = dentry_stat.nr_unused >> 1;
- unsigned long max_value = 4;
-
- if (page_count)
- max_value = -1;
-
- next = tail->prev;
- while (next != &dentry_unused && depth--) {
- struct list_head *tmp = next;
- struct dentry *dentry = list_entry(tmp, struct dentry, d_lru);
- struct inode *inode = dentry->d_inode;
- unsigned long value = 0;
-
- next = tmp->prev;
- if (dentry->d_count) {
- dentry_stat.nr_unused--;
- list_del(tmp);
- INIT_LIST_HEAD(tmp);
- continue;
- }
-
- /*
- * Select dentries based on the page cache count ...
- * should factor in number of uses as well. We take
- * all negative dentries so that they don't accumulate.
- * (We skip inodes that aren't immediately available.)
- */
- if (inode) {
- value = inode->i_nrpages;
- if (value >= max_value)
- continue;
- if (inode->i_state || inode->i_count > 1)
- continue;
- }
-
- /*
- * Move the selected dentries behind the tail.
- */
- if (tmp != tail->prev) {
- list_del(tmp);
- list_add(tmp, tail->prev);
- }
- tail = tmp;
- found++;
- if (inode && --inode_count <= 0)
- break;
- if (page_count && (page_count -= value) <= 0)
- break;
- }
- return found;
-}
-
-/*
* Throw away a dentry - free the inode, dput the parent.
* This requires that the LRU list has already been
* removed.
diff -urN 2.3.18ac9-inode/fs/dquot.c 2.3.18ac9-select_dcache/fs/dquot.c
--- 2.3.18ac9-inode/fs/dquot.c Wed Sep 29 16:04:39 1999
+++ 2.3.18ac9-select_dcache/fs/dquot.c Wed Sep 29 16:08:30 1999
@@ -516,7 +516,6 @@
/*
* Try pruning the dcache to free up some dquots ...
*/
- count = select_dcache(128, 0);
if (count) {
printk(KERN_DEBUG "get_empty_dquot: pruning %d\n", count);
prune_dcache(count);
diff -urN 2.3.18ac9-inode/include/linux/dcache.h 2.3.18ac9-select_dcache/include/linux/dcache.h
--- 2.3.18ac9-inode/include/linux/dcache.h Wed Sep 29 16:04:39 1999
+++ 2.3.18ac9-select_dcache/include/linux/dcache.h Wed Sep 29 16:11:28 1999
@@ -131,7 +131,6 @@
/* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
-extern void prune_dcache(int);
extern void shrink_dcache_sb(struct super_block *);
extern void shrink_dcache_parent(struct dentry *);
extern int d_invalidate(struct dentry *);
@@ -139,9 +138,8 @@
#define shrink_dcache() prune_dcache(0)
/* dcache memory management */
-extern int select_dcache(int, int);
extern int shrink_dcache_memory(int, unsigned int);
-extern void check_dcache_memory(void);
+extern void prune_dcache(int);
/* icache memory management (defined in linux/fs/inode.c) */
extern int shrink_icache_memory(int, int);
Andrea
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/