uint64_t zio_buf_cache_frees[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT];
#endif
-int zio_delay_max = ZIO_DELAY_MAX;
+/* Mark IOs as "slow" if they take longer than 30 seconds */
+int zio_slow_io_ms = (30 * MILLISEC);
#define BP_SPANB(indblkshift, level) \
(((uint64_t)1) << ((level) * ((indblkshift) - SPA_BLKPTRSHIFT)))
* 30 seconds to complete, post an error described the I/O delay.
* We ignore these errors if the device is currently unavailable.
*/
- if (zio->io_delay >= MSEC2NSEC(zio_delay_max)) {
- if (zio->io_vd != NULL && !vdev_is_dead(zio->io_vd))
- zfs_ereport_post(FM_EREPORT_ZFS_DELAY, zio->io_spa,
- zio->io_vd, &zio->io_bookmark, zio, 0, 0);
+ if (zio->io_delay >= MSEC2NSEC(zio_slow_io_ms)) {
+ if (zio->io_vd != NULL && !vdev_is_dead(zio->io_vd)) {
+ /*
+ * We want to only increment our slow IO counters if
+ * the IO is valid (i.e. not if the drive is removed).
+ *
+ * zfs_ereport_post() will also do these checks, but
+ * it can also ratelimit and have other failures, so we
+ * need to increment the slow_io counters independent
+ * of it.
+ */
+ if (zfs_ereport_is_valid(FM_EREPORT_ZFS_DELAY,
+ zio->io_spa, zio->io_vd, zio)) {
+ mutex_enter(&zio->io_vd->vdev_stat_lock);
+ zio->io_vd->vdev_stat.vs_slow_ios++;
+ mutex_exit(&zio->io_vd->vdev_stat_lock);
+
+ zfs_ereport_post(FM_EREPORT_ZFS_DELAY,
+ zio->io_spa, zio->io_vd, &zio->io_bookmark,
+ zio, 0, 0);
+ }
+ }
}
if (zio->io_error) {
EXPORT_SYMBOL(zio_buf_free);
EXPORT_SYMBOL(zio_data_buf_free);
-module_param(zio_delay_max, int, 0644);
-MODULE_PARM_DESC(zio_delay_max, "Max zio millisec delay before posting event");
+module_param(zio_slow_io_ms, int, 0644);
+MODULE_PARM_DESC(zio_slow_io_ms,
+ "Max I/O completion time (milliseconds) before marking it as slow");
module_param(zio_requeue_io_start_cut_in_line, int, 0644);
MODULE_PARM_DESC(zio_requeue_io_start_cut_in_line, "Prioritize requeued I/O");