--- old/usr/src/uts/common/fs/zfs/metaslab.c	Sun Mar  5 21:45:56 2017
+++ new/usr/src/uts/common/fs/zfs/metaslab.c	Sun Mar  5 21:45:56 2017
@@ -1649,7 +1649,7 @@
 	 * In effect, this means that we'll select the metaslab with the most
 	 * free bandwidth rather than simply the one with the most free space.
 	 */
-	if (metaslab_lba_weighting_enabled) {
+	if (!vd->vdev_nonrot && metaslab_lba_weighting_enabled) {
 		weight = 2 * weight - (msp->ms_id * weight) / vd->vdev_ms_count;
 		ASSERT(weight >= space && weight <= 2 * space);
 	}
--- old/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Sun Mar  5 21:45:57 2017
+++ new/usr/src/uts/common/fs/zfs/sys/vdev_impl.h	Sun Mar  5 21:45:57 2017
@@ -152,6 +152,7 @@
 	vdev_stat_t	vdev_stat;	/* virtual device statistics	*/
 	boolean_t	vdev_expanding;	/* expand the vdev?		*/
 	boolean_t	vdev_reopening;	/* reopen in progress?		*/
+	boolean_t	vdev_nonrot;	/* true if SSD, file, or Virtio	*/
 	int		vdev_open_error; /* error on last open		*/
 	kthread_t	*vdev_open_thread; /* thread opening children	*/
 	uint64_t	vdev_crtxg;	/* txg when top-level was added */
--- old/usr/src/uts/common/fs/zfs/vdev.c	Sun Mar  5 21:45:57 2017
+++ new/usr/src/uts/common/fs/zfs/vdev.c	Sun Mar  5 21:45:57 2017
@@ -1106,6 +1106,7 @@
 	vd->vdev_open_thread = curthread;
 	vd->vdev_open_error = vdev_open(vd);
 	vd->vdev_open_thread = NULL;
+	vd->vdev_parent->vdev_nonrot &= vd->vdev_nonrot;
 }
 
 boolean_t
@@ -1126,6 +1127,8 @@
 	taskq_t *tq;
 	int children = vd->vdev_children;
 
+	vd->vdev_nonrot = B_TRUE;
+
 	/*
 	 * in order to handle pools on top of zvols, do the opens
 	 * in a single thread so that the same thread holds the
@@ -1132,9 +1135,11 @@
 	 * spa_namespace_lock
 	 */
 	if (vdev_uses_zvols(vd)) {
-		for (int c = 0; c < children; c++)
+		for (int c = 0; c < children; c++) {
 			vd->vdev_child[c]->vdev_open_error =
 			    vdev_open(vd->vdev_child[c]);
+			vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot;
+		}
 		return;
 	}
 	tq = taskq_create("vdev_open", children, minclsyspri,
@@ -1145,6 +1150,9 @@
 		    TQ_SLEEP) != NULL);
 
 	taskq_destroy(tq);
+
+	for (int c = 0; c < children; c++)
+		vd->vdev_nonrot &= vd->vdev_child[c]->vdev_nonrot;
 }
 
 /*
--- old/usr/src/uts/common/fs/zfs/vdev_disk.c	Sun Mar  5 21:45:57 2017
+++ new/usr/src/uts/common/fs/zfs/vdev_disk.c	Sun Mar  5 21:45:57 2017
@@ -23,6 +23,7 @@
  * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2013 Joyent, Inc.  All rights reserved.
+ * Copyright (c) 2017 James S Blachly, MD <james.blachly@gmail.com>
  */
 
 #include <sys/zfs_context.h>
@@ -271,6 +272,8 @@
 	boolean_t validate_devid = B_FALSE;
 	ddi_devid_t devid;
 	uint64_t capacity = 0, blksz = 0, pbsize;
+	int device_solid_state;
+	char *vendorp;	/* will point to inquiry-vendor-id */
 
 	/*
 	 * We must have a pathname, and it must be absolute.
@@ -543,6 +546,28 @@
 	}
 
 	/*
+	 * Inform the ZIO pipeline if we are non-rotational:
+	 * 1. Check if device is SSD
+	 * 2. If not SSD, check if device is Virtio
+	 */
+	device_solid_state = ldi_prop_get_int(dvd->vd_lh, LDI_DEV_T_ANY,
+	    "device-solid-state", 0);
+	vd->vdev_nonrot = (device_solid_state ? B_TRUE : B_FALSE);
+
+	if (device_solid_state == 0 &&
+	    ldi_prop_exists(dvd->vd_lh, LDI_DEV_T_ANY, "inquiry-vendor-id")) {
+		ldi_prop_lookup_string(dvd->vd_lh, LDI_DEV_T_ANY,
+		    "inquiry-vendor-id", &vendorp);
+		if (strncmp(vendorp, "Virtio", 6) == 0)
+		    vd->vdev_nonrot = B_TRUE;
+		ddi_prop_free(vendorp);
+	}
+
+	cmn_err(CE_NOTE, "[vdev_disk_open] %s :: device-solid-state "
+	    "== %d :: vd->vdev_nonrot == %d\n", vd->vdev_path,
+	    device_solid_state, (int) vd->vdev_nonrot);
+
+	/*
 	 * Clear the nowritecache bit, so that on a vdev_reopen() we will
 	 * try again.
 	 */
--- old/usr/src/uts/common/fs/zfs/vdev_file.c	Sun Mar  5 21:45:58 2017
+++ new/usr/src/uts/common/fs/zfs/vdev_file.c	Sun Mar  5 21:45:58 2017
@@ -58,6 +58,11 @@
 	int error;
 
 	/*
+	 * Rotational optimizations only make sense on block devices
+	 */
+	vd->vdev_nonrot = B_TRUE;
+
+	/*
 	 * We must have a pathname, and it must be absolute.
 	 */
 	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
