Print this page
4334 Improve ZFS N-way mirror read performance

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/vdev_queue.c
          +++ new/usr/src/uts/common/fs/zfs/vdev_queue.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
  25   25  
  26   26  /*
  27   27   * Copyright (c) 2013 by Delphix. All rights reserved.
       28 + * Copyright (c) 2013 Steven Hartland. All rights reserved.
  28   29   */
  29   30  
  30   31  #include <sys/zfs_context.h>
  31   32  #include <sys/vdev_impl.h>
  32   33  #include <sys/spa_impl.h>
  33   34  #include <sys/zio.h>
  34   35  #include <sys/avl.h>
  35   36  #include <sys/dsl_pool.h>
  36   37  
  37   38  /*
↓ open down ↓ 184 lines elided ↑ open up ↑
 222  223                   * they tend to not be tightly clustered anyway so there is
 223  224                   * little to no throughput loss.
 224  225                   */
 225  226                  boolean_t fifo = (p == ZIO_PRIORITY_SYNC_READ ||
 226  227                      p == ZIO_PRIORITY_SYNC_WRITE);
 227  228                  avl_create(&vq->vq_class[p].vqc_queued_tree,
 228  229                      fifo ? vdev_queue_timestamp_compare :
 229  230                      vdev_queue_offset_compare,
 230  231                      sizeof (zio_t), offsetof(struct zio, io_queue_node));
 231  232          }
      233 +
      234 +        vq->vq_lastoffset = 0;
 232  235  }
 233  236  
 234  237  void
 235  238  vdev_queue_fini(vdev_t *vd)
 236  239  {
 237  240          vdev_queue_t *vq = &vd->vdev_queue;
 238  241  
 239  242          for (zio_priority_t p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++)
 240  243                  avl_destroy(&vq->vq_class[p].vqc_queued_tree);
 241  244          avl_destroy(&vq->vq_active_tree);
↓ open down ↓ 476 lines elided ↑ open up ↑
 718  721                          zio_nowait(nio);
 719  722                  } else {
 720  723                          zio_vdev_io_reissue(nio);
 721  724                          zio_execute(nio);
 722  725                  }
 723  726                  mutex_enter(&vq->vq_lock);
 724  727          }
 725  728  
 726  729          mutex_exit(&vq->vq_lock);
 727  730  }
      731 +
      732 +/*
      733 + * As these three methods are only used for load calculations we're not
      734 + * concerned if we get an incorrect value on 32bit platforms due to lack of
      735 + * vq_lock mutex use here, instead we prefer to keep it lock free for
      736 + * performance.
      737 + */
      738 +int
      739 +vdev_queue_length(vdev_t *vd)
      740 +{
      741 +        return (avl_numnodes(&vd->vdev_queue.vq_pending_tree));
      742 +}
      743 +
      744 +uint64_t
      745 +vdev_queue_lastoffset(vdev_t *vd)
      746 +{
      747 +        return (vd->vdev_queue.vq_lastoffset);
      748 +}
      749 +
      750 +void
      751 +vdev_queue_register_lastoffset(vdev_t *vd, zio_t *zio)
      752 +{
      753 +        vd->vdev_queue.vq_lastoffset = zio->io_offset + zio->io_size;
      754 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX