diff options
author | Matthew Macy <[email protected]> | 2020-01-21 15:04:13 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2020-01-21 15:04:13 -0800 |
commit | d3c1e45b7a583e9447b2884c2972987fc49e79c6 (patch) | |
tree | f6ffd944221d0731f568ac966d77ac8f1291f582 /module/zfs | |
parent | 09436c5d885179b302be03d60f0fcc1921745506 (diff) |
Re-consolidate zio_delay_interrupt
With recent SPL changes there is no longer any need for a per
platform version.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Matt Macy <[email protected]>
Closes #9860
Diffstat (limited to 'module/zfs')
-rw-r--r-- | module/zfs/zio.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/module/zfs/zio.c b/module/zfs/zio.c index c0b93346d..ebd7098d6 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -1837,6 +1837,77 @@ zio_interrupt(zio_t *zio) zio_taskq_dispatch(zio, ZIO_TASKQ_INTERRUPT, B_FALSE); } +void +zio_delay_interrupt(zio_t *zio) +{ + /* + * The timeout_generic() function isn't defined in userspace, so + * rather than trying to implement the function, the zio delay + * functionality has been disabled for userspace builds. + */ + +#ifdef _KERNEL + /* + * If io_target_timestamp is zero, then no delay has been registered + * for this IO, thus jump to the end of this function and "skip" the + * delay; issuing it directly to the zio layer. + */ + if (zio->io_target_timestamp != 0) { + hrtime_t now = gethrtime(); + + if (now >= zio->io_target_timestamp) { + /* + * This IO has already taken longer than the target + * delay to complete, so we don't want to delay it + * any longer; we "miss" the delay and issue it + * directly to the zio layer. This is likely due to + * the target latency being set to a value less than + * the underlying hardware can satisfy (e.g. delay + * set to 1ms, but the disks take 10ms to complete an + * IO request). + */ + + DTRACE_PROBE2(zio__delay__miss, zio_t *, zio, + hrtime_t, now); + + zio_interrupt(zio); + } else { + taskqid_t tid; + hrtime_t diff = zio->io_target_timestamp - now; + clock_t expire_at_tick = ddi_get_lbolt() + + NSEC_TO_TICK(diff); + + DTRACE_PROBE3(zio__delay__hit, zio_t *, zio, + hrtime_t, now, hrtime_t, diff); + + if (NSEC_TO_TICK(diff) == 0) { + /* Our delay is less than a jiffy - just spin */ + zfs_sleep_until(zio->io_target_timestamp); + zio_interrupt(zio); + } else { + /* + * Use taskq_dispatch_delay() in the place of + * OpenZFS's timeout_generic(). + */ + tid = taskq_dispatch_delay(system_taskq, + (task_func_t *)zio_interrupt, + zio, TQ_NOSLEEP, expire_at_tick); + if (tid == TASKQID_INVALID) { + /* + * Couldn't allocate a task. Just + * finish the zio without a delay. + */ + zio_interrupt(zio); + } + } + } + return; + } +#endif + DTRACE_PROBE1(zio__delay__skip, zio_t *, zio); + zio_interrupt(zio); +} + static void zio_deadman_impl(zio_t *pio, int ziodepth) { |