Illumos #3618 ::zio dcmd does not show timestamp data
[zfs.git] / module / zfs / vdev_queue.c
index 7ba6389..b2cc6b8 100644 (file)
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
 #include <sys/zfs_context.h>
 #include <sys/vdev_impl.h>
 #include <sys/zio.h>
 int zfs_vdev_max_pending = 10;
 int zfs_vdev_min_pending = 4;
 
-/* deadline = pri + ddi_get_lbolt64() >> time_shift) */
-int zfs_vdev_time_shift = 6;
+/*
+ * The deadlines are grouped into buckets based on zfs_vdev_time_shift:
+ * deadline = pri + gethrtime() >> time_shift)
+ */
+int zfs_vdev_time_shift = 29; /* each bucket is 0.537 seconds */
 
 /* exponential I/O issue ramp-up rate */
 int zfs_vdev_ramp_rate = 2;
@@ -201,7 +208,7 @@ vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit)
        avl_tree_t *t;
        vdev_io_t *vi;
        int flags;
-       uint64_t maxspan = zfs_vdev_aggregation_limit;
+       uint64_t maxspan = MIN(zfs_vdev_aggregation_limit, SPA_MAXBLOCKSIZE);
        uint64_t maxgap;
        int stretch;
 
@@ -312,13 +319,14 @@ again:
 
        if (fio != lio) {
                uint64_t size = IO_SPAN(fio, lio);
-               ASSERT(size <= zfs_vdev_aggregation_limit);
+               ASSERT(size <= maxspan);
                ASSERT(vi != NULL);
 
                aio = zio_vdev_delegated_io(fio->io_vd, fio->io_offset,
                    vi, size, fio->io_type, ZIO_PRIORITY_AGG,
                    flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE,
                    vdev_queue_agg_io_done, NULL);
+               aio->io_timestamp = fio->io_timestamp;
 
                nio = fio;
                do {
@@ -391,7 +399,8 @@ vdev_queue_io(zio_t *zio)
 
        mutex_enter(&vq->vq_lock);
 
-       zio->io_deadline = (ddi_get_lbolt64() >> zfs_vdev_time_shift) +
+       zio->io_timestamp = gethrtime();
+       zio->io_deadline = (zio->io_timestamp >> zfs_vdev_time_shift) +
            zio->io_priority;
 
        vdev_queue_io_add(vq, zio);
@@ -417,10 +426,17 @@ vdev_queue_io_done(zio_t *zio)
        vdev_queue_t *vq = &zio->io_vd->vdev_queue;
        int i;
 
+       if (zio_injection_enabled)
+               delay(SEC_TO_TICK(zio_handle_io_delay(zio)));
+
        mutex_enter(&vq->vq_lock);
 
        avl_remove(&vq->vq_pending_tree, zio);
 
+       zio->io_delta = gethrtime() - zio->io_timestamp;
+       vq->vq_io_complete_ts = gethrtime();
+       vq->vq_io_delta_ts = vq->vq_io_complete_ts - zio->io_timestamp;
+
        for (i = 0; i < zfs_vdev_ramp_rate; i++) {
                zio_t *nio = vdev_queue_io_to_issue(vq, zfs_vdev_max_pending);
                if (nio == NULL)