Date: Sun, 26 Jul 1998 20:18:40 -0700 (PDT) From: Matt Dillon <dillon@best.net> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/7405: pte missing from page directory on write/cluster_write/bdwrite/vfs_clean_pages/vfs_page_set_valid/vm_page_set_validclean/... Message-ID: <199807270318.UAA12620@flea.best.net>
index | next in thread | raw e-mail
>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' <repeats 26 times>, "KwAhEAIAAwAHEAoA\ngIC", 'A' <repeats 11 times>, "oQDADj4+MAAAAAAAEAAAA0EAAAHRASAAE", 'A' <repeats 22 times>, "DMQ\nAAAfECo", 'A' <repeats 50 times>...
},
b_kvabase = 0xf66ab000 "AAAAAAAAAADMQAAAeEBoAAgABAQ", 'A' <repeats 26 times>, "KwAhEAIAAwAHEAoA\ngIC", 'A' <repeats 11 times>, "oQDADj4+MAAAAAAAEAAAA0EAAAHRASAAE", 'A' <repeats 22 times>, "DMQ\nAAAfECo", 'A' <repeats 50 times>...,
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 <repeats 14 times>},
b_npages = 0x2
---Type <return> to continue, or q <return> 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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807270318.UAA12620>
