summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libzpool/Makefile.am1
-rw-r--r--module/os/linux/zfs/Makefile.in1
-rw-r--r--module/os/linux/zfs/zio_os.c103
-rw-r--r--module/zfs/zio.c71
4 files changed, 105 insertions, 71 deletions
diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am
index ca3038f7d..eeff12c69 100644
--- a/lib/libzpool/Makefile.am
+++ b/lib/libzpool/Makefile.am
@@ -151,6 +151,7 @@ KERNEL_C = \
zfs_rlock.c \
zil.c \
zio.c \
+ zio_os.c \
zio_checksum.c \
zio_compress.c \
zio_crypt.c \
diff --git a/module/os/linux/zfs/Makefile.in b/module/os/linux/zfs/Makefile.in
index 1a7ea0d69..c7ff191db 100644
--- a/module/os/linux/zfs/Makefile.in
+++ b/module/os/linux/zfs/Makefile.in
@@ -18,6 +18,7 @@ $(MODULE)-objs += ../os/linux/zfs/qat_crypt.o
$(MODULE)-objs += ../os/linux/zfs/spa_stats.o
$(MODULE)-objs += ../os/linux/zfs/vdev_disk.o
$(MODULE)-objs += ../os/linux/zfs/vdev_file.o
+$(MODULE)-objs += ../os/linux/zfs/zio_os.o
$(MODULE)-objs += ../os/linux/zfs/zfs_acl.o
$(MODULE)-objs += ../os/linux/zfs/zfs_ctldir.o
$(MODULE)-objs += ../os/linux/zfs/zfs_debug.o
diff --git a/module/os/linux/zfs/zio_os.c b/module/os/linux/zfs/zio_os.c
new file mode 100644
index 000000000..207484c4d
--- /dev/null
+++ b/module/os/linux/zfs/zio_os.c
@@ -0,0 +1,103 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019 by Delphix. All rights reserved.
+ * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2017, Intel Corporation.
+ */
+
+#include <sys/sysmacros.h>
+#include <sys/zio.h>
+#include <sys/zio_impl.h>
+#include <sys/time.h>
+#include <sys/trace_defs.h>
+
+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);
+}
diff --git a/module/zfs/zio.c b/module/zfs/zio.c
index 1e341e224..092262590 100644
--- a/module/zfs/zio.c
+++ b/module/zfs/zio.c
@@ -1828,77 +1828,6 @@ 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)
{