Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Jan 2018 05:57:14 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r328254 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201801220557.w0M5vECt062610@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Jan 22 05:57:14 2018
New Revision: 328254
URL: https://svnweb.freebsd.org/changeset/base/328254

Log:
  MFV r328253: 8835 Speculative prefetch in ZFS not working for misaligned reads
  
  illumos/illumos-gate@5cb8d943bc8513c6230589aad5a409d58b0297cb
  
  https://www.illumos.org/issues/8835:
  Sequential reads not aligned to block size are not detected by ZFS
  prefetcher as sequential, killing prefetch and severely hurting
  performance.  It is caused by dmu_zfetch() in case of misaligned
  sequential accesses being called with overlap of one block.
  
  Reviewed by: Matthew Ahrens <mahrens@delphix.com>
  Reviewed by: Allan Jude <allanjude@freebsd.org>
  Approved by: Gordon Ross <gwr@nexenta.com>
  Author: Alexander Motin <mav@FreeBSD.org>

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
Directory Properties:
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c	Mon Jan 22 05:55:43 2018	(r328253)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c	Mon Jan 22 05:57:14 2018	(r328254)
@@ -240,19 +240,33 @@ dmu_zfetch(zfetch_t *zf, uint64_t blkid, uint64_t nblk
 
 	rw_enter(&zf->zf_rwlock, RW_READER);
 
+	/*
+	 * Find matching prefetch stream.  Depending on whether the accesses
+	 * are block-aligned, first block of the new access may either follow
+	 * the last block of the previous access, or be equal to it.
+	 */
 	for (zs = list_head(&zf->zf_stream); zs != NULL;
 	    zs = list_next(&zf->zf_stream, zs)) {
-		if (blkid == zs->zs_blkid) {
+		if (blkid == zs->zs_blkid || blkid + 1 == zs->zs_blkid) {
 			mutex_enter(&zs->zs_lock);
 			/*
 			 * zs_blkid could have changed before we
 			 * acquired zs_lock; re-check them here.
 			 */
-			if (blkid != zs->zs_blkid) {
-				mutex_exit(&zs->zs_lock);
-				continue;
+			if (blkid == zs->zs_blkid) {
+				break;
+			} else if (blkid + 1 == zs->zs_blkid) {
+				blkid++;
+				nblks--;
+				if (nblks == 0) {
+					/* Already prefetched this before. */
+					mutex_exit(&zs->zs_lock);
+					rw_exit(&zf->zf_rwlock);
+					return;
+				}
+				break;
 			}
-			break;
+			mutex_exit(&zs->zs_lock);
 		}
 	}
 



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