panic related to kernel buffer queues
-----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 | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Brian Bergstrand