From owner-freebsd-bugs Sun Jul 26 20:21:05 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id UAA27117 for freebsd-bugs-outgoing; Sun, 26 Jul 1998 20:21:05 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id UAA27107 for ; Sun, 26 Jul 1998 20:21:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.8.8/8.8.5) id UAA18732; Sun, 26 Jul 1998 20:20:01 -0700 (PDT) Received: from flea.best.net (root@flea.best.net [206.184.139.131]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id UAA26869 for ; Sun, 26 Jul 1998 20:19:18 -0700 (PDT) (envelope-from dillon@flea.best.net) Received: (from dillon@localhost) by flea.best.net (8.9.0/8.9.0/best.fl) id UAA12620; Sun, 26 Jul 1998 20:18:40 -0700 (PDT) Message-Id: <199807270318.UAA12620@flea.best.net> Date: Sun, 26 Jul 1998 20:18:40 -0700 (PDT) From: Matt Dillon Reply-To: dillon@best.net To: FreeBSD-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: 3.2 Subject: kern/7405: pte missing from page directory on write/cluster_write/bdwrite/vfs_clean_pages/vfs_page_set_valid/vm_page_set_validclean/... Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 7405 >Category: kern >Synopsis: in pmap_changebit, pmap_pte_quick() returns 0 unexpectedly >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jul 26 20:20:01 PDT 1998 >Last-Modified: >Originator: Matt Dillon >Organization: Best Internet Communications >Release: FreeBSD 2.2.6-STABLE i386 >Environment: FreeBSD-stable, recent CVS (july/98). 128MB ram, PPro-200. >Description: This is the first time I've seen this particular crash, so I guess it doesn't occur often. In this crash a write() call results in a chain of events that winds up causing pmap_changebit() to be called. pmap_changebit() attempts to get the pte address of the VA representing the pages in the bp by calling pmap_pte_quick(). pmap_pte_quick() returns 0 because the page *directory* is missing. pmap_changebit() then proceeds to try to reference the pte address which causes a panic. #17 0xf01c5393 in trap (frame={tf_es = 0x70b0010, tf_ds = 0x10, tf_edi = 0x1000, tf_esi = 0x40, tf_ebp = 0xefbffd0c, tf_isp = 0xefbffce0, tf_ebx = 0xf055463c, tf_edx = 0xf8ebe000, tf_ecx = 0x0, tf_eax = 0x0, tf_trapno = 0xc, tf_err = 0x0, tf_eip = 0xf01c3d24, tf_cs = 0x8, tf_eflags = 0x10246, tf_esp = 0xf0397ec4, tf_ss = 0x0}) at ../../i386/i386/trap.c:324 #18 0xf01c3d24 in pmap_changebit (pa=0x5136000, bit=0x40, setem=0x0) at ../../i386/i386/pmap.c:2753 #19 0xf01c3fcb in pmap_clear_modify (pa=0x5136000) at ../../i386/i386/pmap.c:2919 #20 0xf01b2c0c in vm_page_set_validclean (m=0xf0397ec4, base=0x0, size=0x1000) at ../../vm/vm_page.c:1222 #21 0xf012f3e2 in vfs_page_set_valid (bp=0xf3bf2334, off=0x00000000000ab000, pageno=0x1, m=0xf0397ec4) at ../../kern/vfs_bio.c:1851 #22 0xf012f56f in vfs_clean_pages (bp=0xf3bf2334) at ../../kern/vfs_bio.c:1921 #23 0xf012d2d0 in bdwrite (bp=0xf3bf2334) at ../../kern/vfs_bio.c:404 #24 0xf01307f8 in cluster_write (bp=0xf3bf2334, filesize=0xac000) at ../../kern/vfs_cluster.c:562 #25 0xf01a0844 in ffs_write (ap=0xefbffee8) at ../../ufs/ufs/ufs_readwrite.c:291 #26 0xf01372a7 in vn_write (fp=0xf267e000, uio=0xefbfff34, cred=0xf1b2fb00) at vnode_if.h:283 #27 0xf011a7f3 in write (p=0xf2659e00, uap=0xefbfff94, retval=0xefbfff84) at ../../kern/sys_generic.c:263 #28 0xf01c5f2b in syscall (frame={tf_es = 0x27, tf_ds = 0x27, tf_edi = 0x19000, tf_esi = 0x200b87e4, tf_ebp = 0xefbfc274, tf_isp = 0xefbfffe4, tf_ebx = 0x200a8060, tf_edx = 0x200b87e4, tf_ecx = 0x200b87e4, tf_eax = 0x4, tf_trapno = 0x7, tf_err = 0x7, tf_eip = 0x2009ac71, tf_cs = 0x1f, tf_eflags = 0x202, tf_esp = 0xefbfc25c, tf_ss = 0x27}) at ../../i386/i386/trap.c:920 #29 0x2009ac71 in ?? () ... (kgdb) print *bp $44 = { b_hash = { le_next = 0xf3b8cd90, le_prev = 0xf02027a0 }, b_vnbufs = { le_next = 0x0, le_prev = 0xf3b86fec }, b_freelist = { tqe_next = 0xf3afd62c, tqe_prev = 0xf0202984 }, b_act = { tqe_next = 0x0, tqe_prev = 0xf10a8e54 }, b_proc = 0x0, b_flags = 0x20020290, b_qindex = 0x0, b_usecount = 0x4, b_error = 0x0, b_bufsize = 0x2000, b_bcount = 0x2000, b_resid = 0x0, b_dev = 0xffffffff, b_un = { b_addr = 0xf66ab000 "AAAAAAAAAADMQAAAeEBoAAgABAQ", 'A' , "KwAhEAIAAwAHEAoA\ngIC", 'A' , "oQDADj4+MAAAAAAAEAAAA0EAAAHRASAAE", 'A' , "DMQ\nAAAfECo", 'A' ... }, b_kvabase = 0xf66ab000 "AAAAAAAAAADMQAAAeEBoAAgABAQ", 'A' , "KwAhEAIAAwAHEAoA\ngIC", 'A' , "oQDADj4+MAAAAAAAEAAAA0EAAAHRASAAE", 'A' , "DMQ\nAAAfECo", 'A' ..., b_kvasize = 0x2000, b_saveaddr = 0x0, b_lblkno = 0x55, b_blkno = 0x258ac0, b_iodone = 0, b_iodone_chain = 0x0, b_vp = 0xf1d39e80, b_dirtyoff = 0x0, b_dirtyend = 0x0, b_rcred = 0x0, b_wcred = 0x0, b_validoff = 0x0, b_validend = 0x0, b_pblkno = 0x833263, b_savekva = 0x0, b_driver1 = 0x0, b_driver2 = 0x0, b_spc = 0x0, b_cluster = { cluster_head = { tqh_first = 0xf3afd62c, tqh_last = 0xf3b955e8 }, cluster_entry = { tqe_next = 0xf3afd62c, tqe_prev = 0xf3b955e8 } }, b_pages = {0xf03e3790, 0xf0397ec4, 0x0 }, b_npages = 0x2 ---Type to continue, or q to quit--- } (kgdb) print bp->b_pages[0] $45 = (struct vm_page *) 0xf03e3790 (kgdb) print *bp->b_pages[0] $46 = { pageq = { tqe_next = 0xf02cb290, tqe_prev = 0xf01eb6f8 }, hashq = { tqe_next = 0xf0397ec4, tqe_prev = 0xf0252ea8 }, listq = { tqe_next = 0xf0397ec4, tqe_prev = 0xf02d756c }, object = 0xf2413000, pindex = 0xaa, phys_addr = 0x6875000, queue = 0x0, flags = 0x64, pc = 0x35, wire_count = 0x1, hold_count = 0x0, act_count = 0x0, busy = 0x0, valid = 0xff, dirty = 0x0 } (kgdb) (kgdb) print *bp->b_pages[1] $47 = { pageq = { tqe_next = 0xf0426ec4, tqe_prev = 0xf01eb700 }, hashq = { tqe_next = 0x0, tqe_prev = 0xf03e3798 }, listq = { tqe_next = 0x0, tqe_prev = 0xf03e37a0 }, object = 0xf2413000, pindex = 0xab, phys_addr = 0x5136000, queue = 0x0, flags = 0x64, pc = 0x36, wire_count = 0x1, hold_count = 0x0, act_count = 0x0, busy = 0x0, valid = 0xff, dirty = 0x0 } (kgdb) ------------ (kgdb) frame #18 0xf01c3d24 in pmap_changebit (pa=0x5136000, bit=0x40, setem=0x0) at ../../i386/i386/pmap.c:2753 ../../i386/i386/pmap.c:2753: No such file or directory. (kgdb) (kgdb) print *pv $49 = { pv_pmap = 0xf1c1cd64, pv_va = 0x21704000, pv_list = { tqe_next = 0x0, tqe_prev = 0xf0481358 }, pv_plist = { tqe_next = 0xf05542f4, tqe_prev = 0xf04dca74 }, pv_ptem = 0xf034a7b4 } (kgdb) print *pv->pv_pmap $50 = { pm_pdir = 0xf8ebe000, pm_pteobj = 0xf254cb00, pm_pvlist = { tqh_first = 0xf04da0fc, tqh_last = 0xf0531c34 }, pm_count = 0x1, pm_flags = 0x0, pm_stats = { resident_count = 0x108, wired_count = 0x0 }, pm_ptphint = 0xf03757e4 } (kgdb) print pv->pv_va >> 0x16 $52 = 0x85 (kgdb) print pv->pv_pmap->pm_pdir[pv->pv_va >> 0x16] $51 = (unsigned int *) 0x0 (kgdb) >How-To-Repeat: I know of no way to repeat this. >Fix: No idea. Is pmap_pte_quick allowed to return NULL in this particular case? I looked for instances where pmap->pm_pdir[something] is set to 0. I found one at line 905 of i386/i386/pmap.c in pmap_unwire_pte_hold(). It appears to occur if the vm_page's hold_count is 0. The vm_page's hold count is 0 in this case. pmap_unwire_pte_hold() occurs if a process is swapped out or destroyed. So the question is: if something in the backtrace blocks and the process is swapped out at that point, could this situation occur? If so should a NULL pte be tested for? The process that caused this is shown in the ps below. It is process 18977. shell14:/var/crash# ps -M vmcore.6 -N /kernel -axl UID PID PPID CPU PRI NI VSZ RSS WCHAN STAT TT TIME COMMAND 65534 18789 151631 1 2 0 504 0 select S ?? 0:00.00 (bestwwwd) 120 18899 151631 0 2 0 664 0 sbwait Ss ?? 0:00.00 (ftpd) 0 18914 151631 0 2 0 720 0 select I ?? 0:00.00 (sendmail) 1593 18977 151631 46527 105 0 244 0 - Rs ?? 0:00.00 (popper) 0 19157 151631 0 4 0 192 0 ptcout Is ?? 0:00.00 (telnetd) 2938 20077 151631 0 2 0 900 0 select S ?? 0:00.00 (zass) >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message