Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 06 Dec 2002 14:05:52 -0800
From:      Kirk McKusick <mckusick@beastie.mckusick.com>
To:        Archie Cobbs <archie@dellroad.org>
Cc:        Nate Lawson <nate@root.org>, freebsd-current@FreeBSD.org
Subject:   Re: backgroud fsck is still locking up system (fwd) 
Message-ID:  <200212062205.gB6M5q59093906@beastie.mckusick.com>
In-Reply-To: Your message of "Fri, 06 Dec 2002 13:01:20 PST." <200212062101.gB6L1KaP065709@arch20m.dellroad.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
    From: Archie Cobbs <archie@dellroad.org>
    Subject: Re: backgroud fsck is still locking up system (fwd)
    In-Reply-To: <200212061941.gB6Jf659093594@beastie.mckusick.com>
    To: Kirk McKusick <mckusick@beastie.mckusick.com>
    Date: Fri, 6 Dec 2002 13:01:20 -0800 (PST)
    CC: Archie Cobbs <archie@dellroad.org>, Nate Lawson <nate@root.org>,
       freebsd-current@FreeBSD.org
    X-ASK-Info: Whitelist match

    Kirk McKusick wrote:
    > by the syncer who is also blocked. Could you please run the following
    > command on your system and send me the results:
    > 
    > 	sysctl vfs.lodirtybuffers
    > 	sysctl vfs.hidirtybuffers
    > 	sysctl vfs.numdirtybuffers
    > 
    > both before and after the lockup. If you cannot run this command after
    > the lockup, the global variable names are:
    > 
    > 	lodirtybuffers
    > 	hidirtybuffers
    > 	numdirtybuffers

    Before (system running normally):

	vfs.lodirtybuffers: 126
	vfs.hidirtybuffers: 252
	vfs.numdirtybuffers: 0

    After:

	vfs.lodirtybuffers: 126
	vfs.hidirtybuffers: 252
	vfs.numdirtybuffers: 445

    -Archie

    __________________________________________________________________________
    Archie Cobbs     *     Packet Design     *     http://www.packetdesign.com

OK, it looks like my hypothesis on having a small number of buffers 
and running out of them is the problem. I enclose below a patch which
should check for the problem arising and help to mitigate it. I
would appreciate you dropping it into your kernel and seeing if
it solves your problem. The fix is not ideal, but merely to see
if it solves this problem. If it does, I will figure out how to
do it properly. Thanks for your help.

	Kirk McKusick

Index: sys/buf.h
===================================================================
RCS file: /usr/ncvs/src/sys/sys/buf.h,v
retrieving revision 1.138
diff -c -r1.138 buf.h
*** sys/buf.h	2002/08/30 04:04:37	1.138
--- sys/buf.h	2002/12/06 21:44:25
***************
*** 468,473 ****
--- 468,474 ----
  caddr_t	kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est);
  void	bufinit(void);
  void	bwillwrite(void);
+ int	checkdirtybufs(struct vnode *);
  int	buf_dirty_count_severe(void);
  void	bremfree(struct buf *);
  int	bread(struct vnode *, daddr_t, int, struct ucred *, struct buf **);
Index: kern/vfs_bio.c
===================================================================
RCS file: /usr/ncvs/src/sys/kern/vfs_bio.c,v
retrieving revision 1.342
diff -c -r1.342 vfs_bio.c
*** kern/vfs_bio.c	2002/11/23 19:10:30	1.342
--- kern/vfs_bio.c	2002/12/06 21:44:35
***************
*** 1114,1119 ****
--- 1114,1137 ----
  }
  
  /*
+  * Check to see if a vnode holds too many dirty buffers. If it does,
+  * flush it.
+  */
+ int
+ checkdirtybufs(struct vnode *vp)
+ {
+ 	struct buf *bp;
+ 	int dirtycnt = 0, error = 0;
+ 	struct thread *td = curthread;
+ 
+ 	TAILQ_FOREACH(bp, &vp->v_dirtyblkhd, b_vnbufs)
+ 		dirtycnt++;
+ 	if (dirtycnt > lodirtybuffers)
+ 		error = VOP_FSYNC(vp, td->td_ucred, MNT_NOWAIT, td);
+ 	return (error);
+ }
+ 
+ /*
   * Return true if we have too many dirty buffers.
   */
  int
Index: ufs/ffs/ffs_balloc.c
===================================================================
RCS file: /usr/ncvs/src/sys/ufs/ffs/ffs_balloc.c,v
retrieving revision 1.39
diff -c -r1.39 ffs_balloc.c
*** ufs/ffs/ffs_balloc.c	2002/10/22 01:14:25	1.39
--- ufs/ffs/ffs_balloc.c	2002/12/06 21:49:56
***************
*** 295,300 ****
--- 295,301 ----
  			if (bp->b_bufsize == fs->fs_bsize)
  				bp->b_flags |= B_CLUSTEROK;
  			bdwrite(bp);
+ 			checkdirtybufs(vp);
  		}
  	}
  	/*
***************
*** 335,340 ****
--- 336,342 ----
  			if (bp->b_bufsize == fs->fs_bsize)
  				bp->b_flags |= B_CLUSTEROK;
  			bdwrite(bp);
+ 			checkdirtybufs(vp);
  		}
  		*bpp = nbp;
  		return (0);
***************
*** 756,761 ****
--- 758,764 ----
  			if (bp->b_bufsize == fs->fs_bsize)
  				bp->b_flags |= B_CLUSTEROK;
  			bdwrite(bp);
+ 			checkdirtybufs(vp);
  		}
  	}
  	/*
***************
*** 796,801 ****
--- 799,805 ----
  			if (bp->b_bufsize == fs->fs_bsize)
  				bp->b_flags |= B_CLUSTEROK;
  			bdwrite(bp);
+ 			checkdirtybufs(vp);
  		}
  		*bpp = nbp;
  		return (0);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212062205.gB6M5q59093906>