summaryrefslogtreecommitdiffstats
path: root/module/zfs/vdev_disk.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-10-01 16:54:52 -0700
committerBrian Behlendorf <[email protected]>2010-10-12 14:55:02 -0700
commita69052be7f9a4008e2b09578e9db5fdebc186111 (patch)
tree18744d1316ef69e2ccd5b4410d6cfd72f51ae206 /module/zfs/vdev_disk.c
parent2959d94a0a53612cc1ca9ce9d17df26c3d69a513 (diff)
Initial zio delay timing
While there is no right maximum timeout for a disk IO we can start laying the ground work to measure how long they do take in practice. This change simply measures the IO time and if it exceeds 30s an event is posted for 'zpool events'. This value was carefully selected because for sd devices it implies that at least one timeout (SD_TIMEOUT) has occured. Unfortunately, even with FAILFAST set we may retry and request and not get an error. This behavior is strongly dependant on the device driver and how it is hooked in to the scsi error handling stack. However by setting the limit at 30s we can log the event even if no error was returned. Slightly longer term we can start recording these delays perhaps as a simple power-of-two histrogram. This histogram can then be reported as part of the 'zpool status' command when given an command line option. None of this code changes the internal behavior of ZFS. Currently it is simply for reporting excessively long delays.
Diffstat (limited to 'module/zfs/vdev_disk.c')
-rw-r--r--module/zfs/vdev_disk.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
index 863392544..51062ef23 100644
--- a/module/zfs/vdev_disk.c
+++ b/module/zfs/vdev_disk.c
@@ -95,10 +95,10 @@ static void
vdev_disk_error(zio_t *zio)
{
#ifdef ZFS_DEBUG
- printk("ZFS: zio error=%d type=%d offset=%llu "
- "size=%llu flags=%x\n", zio->io_error, zio->io_type,
+ printk("ZFS: zio error=%d type=%d offset=%llu size=%llu "
+ "flags=%x delay=%llu\n", zio->io_error, zio->io_type,
(u_longlong_t)zio->io_offset, (u_longlong_t)zio->io_size,
- zio->io_flags);
+ zio->io_flags, (u_longlong_t)zio->io_delay);
#endif
}
@@ -242,6 +242,8 @@ vdev_disk_dio_put(dio_request_t *dr)
vdev_disk_dio_free(dr);
if (zio) {
+ zio->io_delay = jiffies_to_msecs(
+ jiffies_64 - zio->io_delay);
zio->io_error = error;
ASSERT3S(zio->io_error, >=, 0);
if (zio->io_error)
@@ -403,6 +405,8 @@ retry:
/* Extra reference to protect dio_request during submit_bio */
vdev_disk_dio_get(dr);
+ if (zio)
+ zio->io_delay = jiffies_64;
/* Submit all bio's associated with this dio */
for (i = 0; i < dr->dr_bio_count; i++)
@@ -442,6 +446,7 @@ BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, size, rc)
{
zio_t *zio = bio->bi_private;
+ zio->io_delay = jiffies_to_msecs(jiffies_64 - zio->io_delay);
zio->io_error = -rc;
if (rc && (rc == -EOPNOTSUPP))
zio->io_vd->vdev_nowritecache = B_TRUE;
@@ -472,6 +477,7 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
bio->bi_end_io = vdev_disk_io_flush_completion;
bio->bi_private = zio;
bio->bi_bdev = bdev;
+ zio->io_delay = jiffies_64;
submit_bio(WRITE_BARRIER, bio);
return 0;