Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jul 2015 15:00:15 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285872 - head/sys/kern
Message-ID:  <201507251500.t6PF0F5J079863@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Jul 25 15:00:14 2015
New Revision: 285872
URL: https://svnweb.freebsd.org/changeset/base/285872

Log:
  With the removal of b_saveaddr in the r285819, b_data must be reset to
  b_kvabase when the buffer is reclaimed.  Otherwise, if b_data for the
  mapped buffer was adjusted with the page-offset portion of b_offset,
  nothing would re-adjust the b_data, which breaks buffer management
  code which expects page-aligned b_data (see e.g. bpman_qenter(), which
  skips partial pages).
  
  Fix a minor issue with the GB_KVAALLOC requests, which could result in
  returning the mapped buffer if the reused buffer is mapped and have
  the right amount of KVA reserved.
  
  Improve assertion in the vfs_buf_check_mapped() to catch unmapped
  buffers which have their b_data incorrectly adjusted with offset.
  
  Reported and tested by:	pho (previous version)
  Reviewed by:	jeff (previous version)
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/kern/vfs_bio.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c	Sat Jul 25 14:06:32 2015	(r285871)
+++ head/sys/kern/vfs_bio.c	Sat Jul 25 15:00:14 2015	(r285872)
@@ -956,6 +956,8 @@ vfs_buf_check_mapped(struct buf *bp)
 	    ("mapped buf: b_kvabase was not updated %p", bp));
 	KASSERT(bp->b_data != unmapped_buf,
 	    ("mapped buf: b_data was not updated %p", bp));
+	KASSERT(bp->b_data < unmapped_buf || bp->b_data > unmapped_buf +
+	    MAXPHYS, ("b_data + b_offset unmapped %p", bp));
 }
 
 static inline void
@@ -2241,6 +2243,7 @@ getnewbuf_reuse_bp(struct buf *bp, int q
 	bp->b_dirtyoff = bp->b_dirtyend = 0;
 	bp->b_bufobj = NULL;
 	bp->b_pin_count = 0;
+	bp->b_data = bp->b_kvabase;
 	bp->b_fsprivate1 = NULL;
 	bp->b_fsprivate2 = NULL;
 	bp->b_fsprivate3 = NULL;
@@ -2528,6 +2531,10 @@ restart:
 			bp->b_flags |= B_INVAL;
 			brelse(bp);
 			goto restart;
+		} else if ((gbflags & (GB_UNMAPPED | GB_KVAALLOC)) ==
+		    (GB_UNMAPPED | GB_KVAALLOC)) {
+			bp->b_data = unmapped_buf;
+			BUF_CHECK_UNMAPPED(bp);
 		}
 		atomic_add_int(&bufreusecnt, 1);
 	}



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