Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Oct 2002 11:46:39 -0400 (EDT)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Kris Kennaway <kris@obsecurity.org>
Cc:        dillon@FreeBSD.org, current@FreeBSD.org
Subject:   RE: Page fault in swapout_procs
Message-ID:  <XFMail.20021018114639.jhb@FreeBSD.org>
In-Reply-To: <20021017215252.GA50026@xor.obsecurity.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 17-Oct-2002 Kris Kennaway wrote:
> I just got the following panic on one of the gohan machines, running a
> somewhat recent -current:
> 
> Fatal trap 12: page fault while in kernel mode
> fault virtual address   = 0xa0
> fault code              = supervisor write, page not present
> instruction pointer     = 0x8:0xc035d0ab
> stack pointer           = 0x10:0xcd25ccc0
> frame pointer           = 0x10:0xcd25cce0
> code segment            = base 0x0, limit 0xfffff, type 0x1b
>                         = DPL 0, pres 1, def32 1, gran 1
> processor eflags        = interrupt enabled, resume, IOPL = 0
> current process         = 3 (vmdaemon)
> kernel: type 12 trap, code=0
> Stopped at      swapout_procs+0x6b:     incl    0xa0(%esi)
> db> Context switches not allowed in the debugger.
> db> trace
> swapout_procs(1,0,68,c0411018,0) at swapout_procs+0x6b
> vm_daemon(0,cd25cd48,c03f1300,34b,0) at vm_daemon+0x6e
> fork_exit(c036b560,0,cd25cd48) at fork_exit+0xaf
> fork_trampoline() at fork_trampoline+0x17

Null pointer dereference.

(gdb) l *swapout_procs+0x6b
0xc036ad1b is in swapout_procs (../../../vm/vm_glue.c:683).
678                      * An aio daemon switches its
679                      * address space while running.
680                      * Perform a quick check whether
681                      * a process has P_SYSTEM.
682                      */
683                     PROC_LOCK(p);
684                     if ((p->p_flag & P_SYSTEM) != 0) {
685                             PROC_UNLOCK(p);
686                             continue;
687                     }

Hmm, if the process is very brand new, it might not have it's
lock setup yet.  Try the patch at
http://www.freebsd.org/~jhb/patches/swapout.patch.

Index: vm_glue.c
===================================================================
RCS file: /usr/cvs/src/sys/vm/vm_glue.c,v
retrieving revision 1.158
diff -u -r1.158 vm_glue.c
--- vm_glue.c   14 Oct 2002 20:31:54 -0000      1.158
+++ vm_glue.c   18 Oct 2002 15:35:08 -0000
@@ -653,28 +653,25 @@
 
        outp = outp2 = NULL;
        outpri = outpri2 = INT_MIN;
 retry:
        sx_slock(&allproc_lock);
        FOREACH_PROC_IN_SYSTEM(p) {
                struct vmspace *vm;
                int minslptime = 100000;
                
                /*
-                * Do not swapout a process that
-                * is waiting for VM data
-                * structures there is a possible
-                * deadlock.  Test this first as
-                * this may block.
-                *
-                * Lock the map until swapout
-                * finishes, or a thread of this
-                * process may attempt to alter
-                * the map.
-                *
                 * Watch out for a process in
                 * creation.  It may have no
-                * address space yet.
-                *
+                * address space or lock yet.
+                */
+               mtx_lock_spin(&sched_lock);
+               if (p->p_state == PRS_NEW) {
+                       mtx_unlock_spin(&sched_lock);
+                       continue;
+               }
+               mtx_unlock_spin(&sched_lock);
+
+               /*
                 * An aio daemon switches its
                 * address space while running.
                 * Perform a quick check whether
@@ -685,17 +682,23 @@
                        PROC_UNLOCK(p);
                        continue;
                }
-               mtx_lock_spin(&sched_lock);
-               if (p->p_state == PRS_NEW) {
-                       mtx_unlock_spin(&sched_lock);
-                       PROC_UNLOCK(p);
-                       continue;
-               }
+
+               /*
+                * Do not swapout a process that
+                * is waiting for VM data
+                * structures as there is a possible
+                * deadlock.  Test this first as
+                * this may block.
+                *
+                * Lock the map until swapout
+                * finishes, or a thread of this
+                * process may attempt to alter
+                * the map.
+                */
                vm = p->p_vmspace;
                KASSERT(vm != NULL,
                        ("swapout_procs: a process has no address space"));
                ++vm->vm_refcnt;
-               mtx_unlock_spin(&sched_lock);
                PROC_UNLOCK(p);
                if (!vm_map_trylock(&vm->vm_map))
                        goto nextproc1;

-- 

John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.20021018114639.jhb>