Hi,

want to summarize my observations wrt the VM-deadlock issue. Everything
tested on UP box bootet with mem=8M and 500M swap.

2.4.0-t9p4 (vanilla)
     deadlocks almost everywhere (even in initscripts!), simple dd with
     large enough bs deadlock's as soon as page_out should start - i.e. no
     swapspace ever used. Fortunately, deadlock can be cured by SysRq+e.

2.4.0-t9p5+vmfixes-2.4.0-test9-A1
     much better, but still some deadlock. Much harder to trigger in a
     reproducible way. "make dep" on /usr/src/linux seems to be a good
     candidate, initscripts too. At some time some (undetermined) process
     hangs - this process remains the only one ever being current forever!
     However EIP still changes according to SysRq+p. This behaviour can
     not be solved by SysRq+[ekil]. SysRq+[sb] not succesful either,
     so its time for unclean reboot und fsck (which deadlocks too).

2.4.0-t9p6 (vanilla)
     very similar to last one. Put some printk() into it to find out, it
     ends up looping forever due to goto try_again in __alloc_pages().
     Just to give it a try I've added a counter to it restricting the
     number of retries (to some arbitrary number - 5 in may case).
     If this is reached I continue to the code following the goto.
     result: no "deadlocks" anymore! I was even able to run the
     initscripts and make bzImage. However, from time to time some
     processes were killed due to lack of memory. sysctl/overcommit_memory
     was 0 and there was plenty of free swapspace.
     Finally I followed Ingo' suggestion to change __GFP_IO to __GFP_WAIT
     in refill_inactive(). With this there was no process killed anymore!
     I was able to complete make bzImage without anything going wrong.
     Furthermore it was possible to start X and login to KDE - although
     the system performance was far from being useable there was no
     problem (besides disk activity). The box run at av. load 2 for
     several hours doing almost nothing but page_in/out. My try_again
     escape was hit quit often (several 1000 times) but the fallback to
     the critical case seems to work. As I printk()'ed the value of
     memory_pressure in this case I can tell the box was running at
     memory_pressure of 30000-40000 for more than 5 hours with peaks
     beyond 50000 when starting X/KDE e.g. - just in case these numbers
     tell you something.

Taken together, the described fix seems to do the job on my system. The
patch vs. vanilla 2.4.0-t9p6 is included below. I would not claim it
to be "Right" or even more than a hack to find out what's going wrong.
Just want to give you some feedback.

PS: vmfixes-2.4.0-test9-B2 not yet tested - will do later.

Regards
Martin


diff -Nur linux-2.4.0-t9p6.orig/mm/page_alloc.c linux-2.4.0-t9p6/mm/page_alloc.c
--- linux-2.4.0-t9p6.orig/mm/page_alloc.c       Mon Sep 25 01:08:52 2000
+++ linux-2.4.0-t9p6/mm/page_alloc.c    Mon Sep 25 01:16:50 2000
@@ -295,6 +295,7 @@
        int direct_reclaim = 0;
        unsigned int gfp_mask = zonelist->gfp_mask;
        struct page * page = NULL;
+       int  retry = 5;
 
        /*
         * Allocations put pressure on the VM subsystem.
@@ -444,9 +445,14 @@
                 * processes, etc).
                 */
                if (gfp_mask & __GFP_WAIT) {
-                       try_to_free_pages(gfp_mask);
-                       memory_pressure++;
-                       goto try_again;
+                       if (--retry > 0) {
+                               try_to_free_pages(gfp_mask);
+                               memory_pressure++;
+                               goto try_again;
+                       }
+                       printk(KERN_CRIT "critical memory fallback\n");
+                       printk("%s - memory_pressure = %i\n",
+                               __FUNCTION__, memory_pressure);
                }
        }
 
diff -Nur linux-2.4.0-t9p6.orig/mm/vmscan.c linux-2.4.0-t9p6/mm/vmscan.c
--- linux-2.4.0-t9p6.orig/mm/vmscan.c   Mon Sep 25 01:08:40 2000
+++ linux-2.4.0-t9p6/mm/vmscan.c        Sun Sep 24 13:14:14 2000
@@ -891,7 +891,7 @@
        do {
                made_progress = 0;
 
-               if (current->need_resched && (gfp_mask & __GFP_IO)) {
+               if (current->need_resched && (gfp_mask & __GFP_WAIT)) {
                        __set_current_state(TASK_RUNNING);
                        schedule();
                }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to