On Mon, 25 Sep 2000, Martin Diehl wrote:

> 
> 
> On Mon, 25 Sep 2000, Martin Diehl wrote:
> 
> > PS: vmfixes-2.4.0-test9-B2 not yet tested - will do later.
> 
> Hi - done now:
> 
> using 2.4.0-t9p6 + vmfixes-2.4.0-test9-B2 I ended up with the box
> deadlocked again! Was "make bzImage" on UP booted with mem=8M.

There is a known deadlock with Ingo's patch.

I'm attaching a patch which should fix it. (on top of
vmfixes-2.4.0-test9-B2) 
diff -Nur --exclude-from=exclude linux.orig/fs/dcache.c linux/fs/dcache.c
--- linux.orig/fs/dcache.c      Mon Sep 25 08:40:47 2000
+++ linux/fs/dcache.c   Mon Sep 25 08:40:53 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 -Nur --exclude-from=exclude linux.orig/fs/inode.c linux/fs/inode.c
--- linux.orig/fs/inode.c       Mon Sep 25 08:40:47 2000
+++ linux/fs/inode.c    Mon Sep 25 08:40:53 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 -Nur --exclude-from=exclude linux.orig/mm/slab.c linux/mm/slab.c
--- linux.orig/mm/slab.c        Mon Sep 25 08:40:38 2000
+++ linux/mm/slab.c     Mon Sep 25 08:40:53 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);

Reply via email to