panic related to kernel buffer queues
panic related to kernel buffer queues
- Subject: panic related to kernel buffer queues
- From: Brian Bergstrand <email@hidden>
- Date: Sat, 1 Nov 2003 20:05:49 -0600
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I have a panic problem with my filesystem that I've traced down to
getnewbuf() reusing a buffer that is locked.
(gdb) bt 10
#0 Debugger (message=0x2952a0 "panic") at
/SourceCache/xnu/xnu-517/osfmk/ppc/model_dep.c:627
#1 0x0001ed8c in panic (str=0x29a40c "getnewbuf: bp @ 0x%x is LOCKED!
(flags 0x%x)\n") at /SourceCache/xnu/xnu-517/osfmk/kern/debug.c:198
#2 0x000b51e8 in getnewbuf (slpflag=0, slptimeo=0, queue=0x1264b928)
at /SourceCache/xnu/xnu-517/bsd/vfs/vfs_bio.c:1687
#3 0x000b4398 in getblk (vp=0x2f98448, blkno=0, size=4096, slpflag=0,
slptimeo=0, operation=16) at
/SourceCache/xnu/xnu-517/bsd/vfs/vfs_bio.c:1183
#4 0x224720b8 in ext2_balloc2 (ip=0x2f83404, bn=0, size=24,
cred=0x1ed578c, bpp=0x1264bae0, flags=3, blk_alloc=0x0) at
src/gnu/ext2fs/ext2_balloc.c:180
#5 0x2247e858 in ext2_write (ap=0x1264bc70) at
src/gnu/ext2fs/ext2_extern.h:120
#6 0x000cd334 in vn_rdwr (rw=UIO_WRITE, vp=0x2f98448, base=0x1264bd40
"\002", len=24, offset=68, segflg=UIO_SYSSPACE, ioflg=308591728,
cred=0x1ed578c, aresid=0x0, p=0x0) at
/SourceCache/xnu/xnu-517/bsd/sys/vnode_if.h:387
#7 0x22481e48 in ext2_mkdir (ap=0x1264bed0) at
src/gnu/ext2fs/ext2_vnops.c:1658
#8 0x000c919c in mkdir (p=0x2199d40, uap=0x1f94af4, retval=0x1) at
/SourceCache/xnu/xnu-517/bsd/sys/vnode_if.h:679
#9 0x0023daa4 in unix_syscall (regs=0x1cafcc8) at
/SourceCache/xnu/xnu-517/bsd/dev/ppc/systemcalls.c:155
Turns out that the buffer ends up on BQ_META, even though the buffer
thinks it's on BQ_LOCKED. My question: is it possible for a buffer to
be on multiple queues? And if so, it seems as if there is a bug in
getnewbuf().
Here is what I'm doing:
meta_bread() is used to read the block into a buffer, then the buf is
inserted into a LRU cache (the block is either an inode or block
bitmap, and is cached on the assumption that it will be used
frequently), then the buf is locked with:
#define LCK_BUF(bp) { \
int s; \
s = splbio(); \
(bp)->b_flags |= B_LOCKED; \
splx(s); \
brelse(bp); \
}
When the buffer is pushed out of the cache, the following is used to
unlock it and sync it to disk:
#define ULCK_BUF(bp) { \
long flags; \
int s; \
s = splbio(); \
flags = (bp)->b_flags; \
(bp)->b_flags &= ~(B_DIRTY | B_LOCKED); \
bremfree(bp); \
splx(s); \
if (flags & B_DIRTY) \
bwrite(bp); \
else \
brelse(bp); \
}
Here is the buffer at the time of the panic:
(gdb) p *(struct buf*)0x1d89f2d4
$4 = {
b_hash = {
le_next = 0x1d89fd38,
le_prev = 0x1d89ede8
},
b_vnbufs = {
le_next = 0x1d89fd38,
le_prev = 0x1d89ef08
},
b_freelist = {
tqe_next = 0x1d8cfa4c,
tqe_prev = 0x336a20
},
b_proc = 0x0,
b_flags = 1610629920,
b_error = 0,
b_bufsize = 4096,
b_bcount = 4096,
b_resid = 0,
b_dev = 234881028,
b_un = {
b_addr = 0x2563000 '' <repeats 65 times>, "\177", ''
<repeats 19 times>,
"\200\201\201\203\200\201\201\200\201\201\201\201\201\201\201\201\203\20
1\200\201\201\201\201\201\200\201\201\200\200\017\f\0300`\003\017\fx",
'' <repeats 20 times>, "\a\001\003", '' <repeats 16 times>,
"\201\003\a\003\003\003\a\002\006\036\006\004\004\004\004\004\004\004\00
4\004@\201\200"...
},
b_saveaddr = 0x0,
b_lblkno = 6291456,
b_blkno = 6291456,
b_iodone = 0,
b_vp = 0x24f89a0,
b_dirtyoff = 0,
b_dirtyend = 0,
b_validoff = 0,
b_validend = 0,
b_rcred = 0x0,
b_wcred = 0x0,
b_timestamp = 1067707777,
b_vectorcount = 0,
b_vectorlist = 0x0,
b_pagelist = 0x0,
b_vects = {0, 0},
b_whichq = 0,
b_act = {
tqe_next = 0x0,
tqe_prev = 0x0
},
b_drvdata = 0x24cc300
}
b_flags == B_CACHE,B_DIRTY,B_DONE,B_LOCKED,B_ZALLOC,B_META
As you can see, b_whichq says it's on BQ_LOCKED. I tried to confirm
this by tracing down the queue, but after about 25 entries I gave up.
But, when the panic happens the buffer is the first entry on BQ_META
(the fourth queue, BQ_LOCKED is queue 0):
(gdb) p bufqueues
$13 = {{
tqh_first = 0x1d0fcf28,
tqh_last = 0x1d0d82c8
}, {
tqh_first = 0x0,
tqh_last = 0x336a08
}, {
tqh_first = 0x0,
tqh_last = 0x336a10
}, {
tqh_first = 0x0,
tqh_last = 0x336a18
}, {
tqh_first = 0x1d0e0198,
tqh_last = 0x1d0dfd48
}, {
tqh_first = 0x0,
tqh_last = 0x336a28
}}
And here is my bitmap cache at the time of the panic, in which the
buffer is entry #5. Entry #0 is the most recent, and entry #7 is the
least recent.
s_inode_bitmap = {0x1d0d83d0, 0x1d0f94a4, 0x1d0d9cf8, 0x1d0e0eb8,
0x1d0da2fc, 0x1d0e0198, 0x1d0df3ec, 0x1d0df8d8},
So, anyone have any ideas as to what is going on? I'd appreciate any
thoughts at all.
Thanks.
Brian Bergstrand <
http://www.classicalguitar.net/brian/>
PGP Key: <
http://www.classicalguitar.net/brian/misc/public_key.txt>
We hang the petty thieves and appoint the great ones to public office.
- - Aesop
As of 07:44:06 PM, iTunes is playing "Lullaby" from "Thirteenth Step"
by "A Perfect Circle"
-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0.2
iQA/AwUBP6RYc3nR2Fu2x7aiEQIxQwCgll0VjQMGP3sau6gRJTXxqJLAR4cAoMm7
botl9h9EORNc0ZiMFF+EVA3x
=lSJW
-----END PGP SIGNATURE-----
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.