Subject: Re: kern/33406: softdeps get stuck in endless loop
To: None <gnats-bugs@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: netbsd-bugs
Date: 05/02/2006 00:52:09
With the following patches running on an i386 with a 115200 baud serial
console, I can reproduce this problem using the lat_fs recipe in the PR.

The Debugger call in vfs_subr.c drops you to ddb after a while.  You
may need to "c"ontinue a couple of times before you see the problem.  I
added the Debugger check since sending a BREAK to the serial console
didn't drop in to ddb while the console was busying sending so much
output.


Index: kern/vfs_bio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_bio.c,v
retrieving revision 1.159
diff -d -p -u -r1.159 vfs_bio.c
--- kern/vfs_bio.c	5 Apr 2006 00:52:16 -0000	1.159
+++ kern/vfs_bio.c	1 May 2006 14:06:31 -0000
@@ -735,7 +735,10 @@ bwrite(struct buf *bp)
 	 * vnode queue.
 	 */
 	if (wasdelayed)
+{
+printf("bwrite: reassignbuf\n");
 		reassignbuf(bp, bp->b_vp);
+}
 	else
 		p->p_stats->p_ru.ru_oublock++;
 
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_subr.c,v
retrieving revision 1.265
diff -d -p -u -r1.265 vfs_subr.c
--- kern/vfs_subr.c	25 Feb 2006 07:11:31 -0000	1.265
+++ kern/vfs_subr.c	1 May 2006 14:06:32 -0000
@@ -862,6 +862,9 @@ vflushbuf(struct vnode *vp, int sync)
 loop:
 	s = splbio();
 	for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
+static int loops = 0;
+if (loops++ % 1000 == 0)
+ Debugger();
 		nbp = LIST_NEXT(bp, b_vnbufs);
 		simple_lock(&bp->b_interlock);
 		if ((bp->b_flags & B_BUSY)) {
Index: ufs/ffs/ffs_softdep.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_softdep.c,v
retrieving revision 1.73
diff -d -p -u -r1.73 ffs_softdep.c
--- ufs/ffs/ffs_softdep.c	24 Dec 2005 20:45:10 -0000	1.73
+++ ufs/ffs/ffs_softdep.c	1 May 2006 14:06:33 -0000
@@ -4032,6 +4032,7 @@ softdep_disk_write_complete(bp)
 	/*
 	 * Reattach any requests that must be redone.
 	 */
+printf("reattach loop\n");
 	while ((wk = LIST_FIRST(&reattach)) != NULL) {
 		WORKLIST_REMOVE(wk);
 		WORKLIST_INSERT(&bp->b_dep, wk);