]> granicus.if.org Git - zfs/commitdiff
vdev_mirror: kstat observables for preferred vdev
authorGvozden Neskovic <neskovic@gmail.com>
Fri, 4 Aug 2017 10:23:10 +0000 (12:23 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 21 Aug 2017 17:05:54 +0000 (10:05 -0700)
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Gvozden Neskovic <neskovic@gmail.com>
Closes #6461

include/sys/spa.h
module/zfs/spa_misc.c
module/zfs/vdev_mirror.c

index f6d2a5a711a3c23100ee03a65506b2e558df1a15..d4661f4d38f8456bf1a5ab2b27a2626469156f6e 100644 (file)
@@ -1034,6 +1034,10 @@ extern void spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub);
 extern void vdev_cache_stat_init(void);
 extern void vdev_cache_stat_fini(void);
 
+/* vdev mirror */
+extern void vdev_mirror_stat_init(void);
+extern void vdev_mirror_stat_fini(void);
+
 /* Initialization and termination */
 extern void spa_init(int flags);
 extern void spa_fini(void);
index 14723a1ca9be0b218c10bc2a871aa231f0584fbb..78e72aaf32926dfc25cb22294d6d1866b7d591b7 100644 (file)
@@ -1897,6 +1897,7 @@ spa_init(int mode)
        dmu_init();
        zil_init();
        vdev_cache_stat_init();
+       vdev_mirror_stat_init();
        vdev_raidz_math_init();
        vdev_file_init();
        zfs_prop_init();
@@ -1916,6 +1917,7 @@ spa_fini(void)
 
        vdev_file_fini();
        vdev_cache_stat_fini();
+       vdev_mirror_stat_fini();
        vdev_raidz_math_fini();
        zil_fini();
        dmu_fini();
index 0cf2bc66500d4f4e49374be4ffc8fc1975732866..27a6bb932f444e52264c3bd4153ef2b459d3b106 100644 (file)
 #include <sys/abd.h>
 #include <sys/fs/zfs.h>
 
+/*
+ * Vdev mirror kstats
+ */
+static kstat_t *mirror_ksp = NULL;
+
+typedef struct mirror_stats {
+       kstat_named_t vdev_mirror_stat_rotating_linear;
+       kstat_named_t vdev_mirror_stat_rotating_offset;
+       kstat_named_t vdev_mirror_stat_rotating_seek;
+       kstat_named_t vdev_mirror_stat_non_rotating_linear;
+       kstat_named_t vdev_mirror_stat_non_rotating_seek;
+
+       kstat_named_t vdev_mirror_stat_preferred_found;
+       kstat_named_t vdev_mirror_stat_preferred_not_found;
+} mirror_stats_t;
+
+static mirror_stats_t mirror_stats = {
+       /* New I/O follows directly the last I/O */
+       { "rotating_linear",                    KSTAT_DATA_UINT64 },
+       /* New I/O is within zfs_vdev_mirror_rotating_seek_offset of the last */
+       { "rotating_offset",                    KSTAT_DATA_UINT64 },
+       /* New I/O requires random seek */
+       { "rotating_seek",                      KSTAT_DATA_UINT64 },
+       /* New I/O follows directly the last I/O  (nonrot) */
+       { "non_rotating_linear",                KSTAT_DATA_UINT64 },
+       /* New I/O requires random seek (nonrot) */
+       { "non_rotating_seek",                  KSTAT_DATA_UINT64 },
+       /* Preferred child vdev found */
+       { "preferred_found",                    KSTAT_DATA_UINT64 },
+       /* Preferred child vdev not found or equal load  */
+       { "preferred_not_found",                KSTAT_DATA_UINT64 },
+
+};
+
+#define        MIRROR_STAT(stat)               (mirror_stats.stat.value.ui64)
+#define        MIRROR_INCR(stat, val)          atomic_add_64(&MIRROR_STAT(stat), val)
+#define        MIRROR_BUMP(stat)               MIRROR_INCR(stat, 1)
+
+void
+vdev_mirror_stat_init(void)
+{
+       mirror_ksp = kstat_create("zfs", 0, "vdev_mirror_stats",
+           "misc", KSTAT_TYPE_NAMED,
+           sizeof (mirror_stats) / sizeof (kstat_named_t), KSTAT_FLAG_VIRTUAL);
+       if (mirror_ksp != NULL) {
+               mirror_ksp->ks_data = &mirror_stats;
+               kstat_install(mirror_ksp);
+       }
+}
+
+void
+vdev_mirror_stat_fini(void)
+{
+       if (mirror_ksp != NULL) {
+               kstat_delete(mirror_ksp);
+               mirror_ksp = NULL;
+       }
+}
+
 /*
  * Virtual device vector for mirroring.
  */
@@ -140,8 +199,10 @@ vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
 
        if (vd->vdev_nonrot) {
                /* Non-rotating media. */
-               if (last_offset == zio_offset)
+               if (last_offset == zio_offset) {
+                       MIRROR_BUMP(vdev_mirror_stat_non_rotating_linear);
                        return (load + zfs_vdev_mirror_non_rotating_inc);
+               }
 
                /*
                 * Apply a seek penalty even for non-rotating devices as
@@ -149,12 +210,15 @@ vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
                 * the device, thus avoiding unnecessary per-command overhead
                 * and boosting performance.
                 */
+               MIRROR_BUMP(vdev_mirror_stat_non_rotating_seek);
                return (load + zfs_vdev_mirror_non_rotating_seek_inc);
        }
 
        /* Rotating media I/O's which directly follow the last I/O. */
-       if (last_offset == zio_offset)
+       if (last_offset == zio_offset) {
+               MIRROR_BUMP(vdev_mirror_stat_rotating_linear);
                return (load + zfs_vdev_mirror_rotating_inc);
+       }
 
        /*
         * Apply half the seek increment to I/O's within seek offset
@@ -162,10 +226,13 @@ vdev_mirror_load(mirror_map_t *mm, vdev_t *vd, uint64_t zio_offset)
         * of a seek increment.
         */
        offset_diff = (int64_t)(last_offset - zio_offset);
-       if (ABS(offset_diff) < zfs_vdev_mirror_rotating_seek_offset)
+       if (ABS(offset_diff) < zfs_vdev_mirror_rotating_seek_offset) {
+               MIRROR_BUMP(vdev_mirror_stat_rotating_offset);
                return (load + (zfs_vdev_mirror_rotating_seek_inc / 2));
+       }
 
        /* Apply the full seek increment to all other I/O's. */
+       MIRROR_BUMP(vdev_mirror_stat_rotating_seek);
        return (load + zfs_vdev_mirror_rotating_seek_inc);
 }
 
@@ -387,12 +454,15 @@ vdev_mirror_child_select(zio_t *zio)
                mm->mm_preferred_cnt++;
        }
 
-       if (mm->mm_preferred_cnt == 1)
+       if (mm->mm_preferred_cnt == 1) {
+               MIRROR_BUMP(vdev_mirror_stat_preferred_found);
                return (mm->mm_preferred[0]);
+       }
 
-
-       if (mm->mm_preferred_cnt > 1)
+       if (mm->mm_preferred_cnt > 1) {
+               MIRROR_BUMP(vdev_mirror_stat_preferred_not_found);
                return (vdev_mirror_preferred_child_randomize(zio));
+       }
 
        /*
         * Every device is either missing or has this txg in its DTL.