diff --exclude-from=exclude -Nur linux.orig/fs/dcache.c linux/fs/dcache.c --- linux.orig/fs/dcache.c Sun Sep 24 18:14:24 2000 +++ linux/fs/dcache.c Sun Sep 24 22:49:16 2000 @@ -556,15 +556,11 @@ int count = 0; if (priority) count = dentry_stat.nr_unused / priority; - prune_dcache(count); - /* FIXME: kmem_cache_shrink here should tell us - the number of pages freed, and it should - work in a __GFP_DMA/__GFP_HIGHMEM behaviour - to free only the interesting pages in - function of the needs of the current allocation. */ - kmem_cache_shrink(dentry_cache); - return 0; + if(gfp_mask & __GFP_IO) + prune_dcache(count); + + return kmem_cache_shrink(dentry_cache); } #define NAME_ALLOC_LEN(len) ((len+16) & ~15) diff --exclude-from=exclude -Nur linux.orig/fs/inode.c linux/fs/inode.c --- linux.orig/fs/inode.c Sun Sep 24 18:14:25 2000 +++ linux/fs/inode.c Sun Sep 24 22:47:30 2000 @@ -460,15 +460,11 @@ if (priority) count = inodes_stat.nr_unused / priority; - prune_icache(count); - /* FIXME: kmem_cache_shrink here should tell us - the number of pages freed, and it should - work in a __GFP_DMA/__GFP_HIGHMEM behaviour - to free only the interesting pages in - function of the needs of the current allocation. */ - kmem_cache_shrink(inode_cachep); - return 0; + if(gfp_mask & __GFP_IO) + prune_icache(count); + + return kmem_cache_shrink(inode_cachep); } /* diff --exclude-from=exclude -Nur linux.orig/mm/slab.c linux/mm/slab.c --- linux.orig/mm/slab.c Sun Sep 24 18:14:04 2000 +++ linux/mm/slab.c Sun Sep 24 22:46:11 2000 @@ -887,7 +887,7 @@ static int __kmem_cache_shrink(kmem_cache_t *cachep) { slab_t *slabp; - int ret; + int ret, freed = 0; drain_cpu_caches(cachep); @@ -912,8 +912,11 @@ spin_unlock_irq(&cachep->spinlock); kmem_slab_destroy(cachep, slabp); spin_lock_irq(&cachep->spinlock); + + freed++; } - ret = !list_empty(&cachep->slabs); + + ret = ((1 << cachep->gfporder) * freed); spin_unlock_irq(&cachep->spinlock); return ret; } @@ -923,7 +926,8 @@ * @cachep: The cache to shrink. * * Releases as many slabs as possible for a cache. - * To help debugging, a zero exit status indicates all slabs were released. + * + * Returns the amount of freed pages. */ int kmem_cache_shrink(kmem_cache_t *cachep) { @@ -962,7 +966,9 @@ list_del(&cachep->next); up(&cache_chain_sem); - if (__kmem_cache_shrink(cachep)) { + __kmem_cache_shrink(cachep); + + if (!list_empty(&cachep->slabs)) { printk(KERN_ERR "kmem_cache_destroy: Can't free all objects %p\n", cachep); down(&cache_chain_sem); diff --exclude-from=exclude -Nur linux.orig/mm/vmscan.c linux/mm/vmscan.c --- linux.orig/mm/vmscan.c Sun Sep 24 18:14:04 2000 +++ linux/mm/vmscan.c Sun Sep 24 23:09:01 2000 @@ -904,14 +904,16 @@ } /* Try to get rid of some shared memory pages.. */ - if (gfp_mask & __GFP_IO) { - /* - * don't be too light against the d/i cache since - * shrink_mmap() almost never fail when there's - * really plenty of memory free. - */ - count -= shrink_dcache_memory(priority, gfp_mask); - count -= shrink_icache_memory(priority, gfp_mask); + + /* + * don't be too light against the d/i cache since + * shrink_mmap() almost never fail when there's + * really plenty of memory free. + */ + count -= shrink_dcache_memory(priority, gfp_mask); + count -= shrink_icache_memory(priority, gfp_mask); + + if(gfp_mask & __GFP_IO) { /* * Not currently working, see fixme in shrink_?cache_memory * In the inner funtions there is a comment: @@ -992,10 +994,8 @@ * the inode and dentry cache whenever we do this. */ if (free_shortage() || inactive_shortage()) { - if (gfp_mask & __GFP_IO) { - ret += shrink_dcache_memory(6, gfp_mask); - ret += shrink_icache_memory(6, gfp_mask); - } + ret += shrink_dcache_memory(6, gfp_mask); + ret += shrink_icache_memory(6, gfp_mask); ret += refill_inactive(gfp_mask, user); } else {