Author: mav
Date: Mon Jan 22 05:55:43 2018
New Revision: 328253
URL: https://svnweb.freebsd.org/changeset/base/328253

Log:
  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 <mahr...@delphix.com>
  Reviewed by: Allan Jude <allanj...@freebsd.org>
  Approved by: Gordon Ross <g...@nexenta.com>
  Author: Alexander Motin <m...@freebsd.org>

Modified:
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_zfetch.c

Modified: vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_zfetch.c
==============================================================================
--- vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_zfetch.c      Mon Jan 22 
05:52:39 2018        (r328252)
+++ vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_zfetch.c      Mon Jan 22 
05:55:43 2018        (r328253)
@@ -224,19 +224,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);
                }
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to