Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Apr 1998 11:21:32 -0700 (PDT)
From:      Matt Dillon <dillon@best.net>
To:        Poul-Henning Kamp <phk@FreeBSD.ORG>
Cc:        freebsd-bugs@FreeBSD.ORG
Subject:   Re: kern/6258
Message-ID:  <199804151821.LAA28517@flea.best.net>

next in thread | raw e-mail | index | archive | help
:
:Old Synopsis: A fix required to prevent kernel lockups in brelse causes the dump program to lockup in 'newbuf'
:New Synopsis: A fix required to prevent kernel lockups in brelse causes the dump program to lockup in 'newbuf' [2.2 ISSUE]
:
:State-Changed-From-To: open-analyzed
:State-Changed-By: phk
:State-Changed-When: Wed Apr 15 10:08:26 PDT 1998
:State-Changed-Why: 
:merge to 2.2 issue

    Oh, I should add something to the bug report... in email I think the 
    FreeBSD folks decided to fold in the -current changes to fix this problem.  
    The patch I included in the bug report would therefore not be used.

    However, since I did submit the patch I should probably submit an update
    to it as the patch I submitted has a bug in.  The bp scan I added in the
    patch overwrites the 'bp' variable which is used later on.

					-Matt

    Matthew Dillon   Engineering, BEST Internet Communications, Inc.
		    <dillon@best.net>
    [always include a portion of the original email in any response!]


--- LINK/vfs_bio.c	Fri Mar 13 13:13:57 1998
+++ vfs_bio.c	Mon Apr 13 17:21:49 1998
@@ -597,10 +597,12 @@
 		LIST_REMOVE(bp, b_hash);
 		LIST_INSERT_HEAD(&invalhash, bp, b_hash);
 		bp->b_dev = NODEV;
+#ifdef notdef
 		/*
 		 * Get rid of the kva allocation *now*
 		 */
 		bfreekva(bp);
+#endif
 		if (needsbuffer) {
 			wakeup(&needsbuffer);
 			needsbuffer=0;
@@ -986,9 +988,34 @@
 		 */
 		if (vm_map_findspace(buffer_map,
 			vm_map_min(buffer_map), maxsize, &addr)) {
-			bp->b_flags |= B_INVAL;
-			brelse(bp);
-			goto trytofreespace;
+				struct buf *bp2;
+
+			/*
+			 * Matt hack.  Since we can't call bfreekva() in
+			 * brelse(), the bp's on the EMPTY list may all
+			 * still have allocated KVM.  If we can't find
+			 * unused space in the buffer_map, we should try
+			 * to defragment the map by freeing as much from
+			 * the empty list as possible.
+			 */
+			printf("vm_map_findspace() failed, defragmenting freelist\n");
+			for (bp2 = TAILQ_FIRST(&bufqueues[QUEUE_EMPTY]);
+				bp2;
+				bp2 = TAILQ_NEXT(bp2, b_freelist)
+			) {
+			    if (bp2->b_kvasize)
+				bfreekva(bp2);
+			    if (bp2->b_qindex != QUEUE_EMPTY)
+				break;
+			}
+			addr = 0;
+			if (vm_map_findspace(buffer_map,
+				vm_map_min(buffer_map), maxsize, &addr)) {
+
+				bp->b_flags |= B_INVAL;
+				brelse(bp);
+				goto trytofreespace;
+			}
 		}
 	}
 

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



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