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

@@ -23,10 +23,11 @@
  * Use is subject to license terms.
  */
 
 /*
  * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
 #include <sys/vdev_impl.h>
 #include <sys/spa_impl.h>

@@ -227,10 +228,12 @@
                 avl_create(&vq->vq_class[p].vqc_queued_tree,
                     fifo ? vdev_queue_timestamp_compare :
                     vdev_queue_offset_compare,
                     sizeof (zio_t), offsetof(struct zio, io_queue_node));
         }
+
+        vq->vq_last_queued_offset = 0;
 }
 
 void
 vdev_queue_fini(vdev_t *vd)
 {

@@ -723,5 +726,35 @@
                 mutex_enter(&vq->vq_lock);
         }
 
         mutex_exit(&vq->vq_lock);
 }
+
+/*
+ * As these three methods are only used for load calculations we're not
+ * concerned if we get an incorrect value on 32bit platforms due to lack of
+ * vq_lock mutex use here, instead we prefer to keep it lock free for
+ * performance.
+ */
+int
+vdev_queue_length(vdev_t *vd)
+{
+        vdev_queue_t *vq = &vd->vdev_queue;
+        int len = 0;
+
+        for (zio_priority_t p = 0; p < ZIO_PRIORITY_NUM_QUEUEABLE; p++)
+                len += avl_numnodes(&vq->vq_class[p].vqc_queued_tree);
+
+        return (len);
+}
+
+uint64_t
+vdev_queue_last_queued_offset(vdev_t *vd)
+{
+        return (vd->vdev_queue.vq_last_queued_offset);
+}
+
+void
+vdev_queue_register_last_queued_offset(vdev_t *vd, zio_t *zio)
+{
+        vd->vdev_queue.vq_last_queued_offset = zio->io_offset + zio->io_size;
+}