From 9221de36f3928098508dbe7df65dd2e3261f4208 Mon Sep 17 00:00:00 2001 From: kernelOfTruth Date: Fri, 13 Mar 2015 00:51:59 +0100 Subject: [PATCH] Revert "Illumos #5244 zio pipeline callers should explicitly invoke next stage #2828" This reverts commit 92912798386e59ea0043684944c21f53de565b82. conflicts with: commit 92119cc259ee2f9ebde14145f549d6313f557759 Author: Brian Behlendorf Date: Sun Jul 13 14:35:19 2014 -0400 Mark IO pipeline with PF_FSTRANS In order to avoid deadlocking in the IO pipeline it is critical that pageout be avoided during direct memory reclaim. This ensures that the pipeline threads can always make forward progress and never end up blocking on a DMU transaction. For this very reason Linux now provides the PF_FSTRANS flag which may be set in the process context. Signed-off-by: Brian Behlendorf not sure where that commit came from, it's not in master (?!) but commits where always fetched from master /sadpanda --- include/sys/vdev_impl.h | 2 +- include/sys/zio.h | 3 +++ lib/libzpool/taskq.c | 4 ---- module/zfs/vdev_disk.c | 20 +++++++++----------- module/zfs/vdev_file.c | 12 ++++++------ module/zfs/vdev_mirror.c | 9 ++++----- module/zfs/vdev_missing.c | 6 +++--- module/zfs/vdev_raidz.c | 9 ++++----- module/zfs/zio.c | 23 +++-------------------- 9 files changed, 33 insertions(+), 55 deletions(-) diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h index fd6eddc0444d..6dae2955b847 100644 --- a/include/sys/vdev_impl.h +++ b/include/sys/vdev_impl.h @@ -60,7 +60,7 @@ typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size, uint64_t *ashift); typedef void vdev_close_func_t(vdev_t *vd); typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); -typedef void vdev_io_start_func_t(zio_t *zio); +typedef int vdev_io_start_func_t(zio_t *zio); typedef void vdev_io_done_func_t(zio_t *zio); typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef void vdev_hold_func_t(vdev_t *vd); diff --git a/include/sys/zio.h b/include/sys/zio.h index 350063c739b8..e1b1b8c705cc 100644 --- a/include/sys/zio.h +++ b/include/sys/zio.h @@ -154,6 +154,9 @@ typedef enum zio_priority { ZIO_PRIORITY_NOW /* non-queued i/os (e.g. free) */ } zio_priority_t; +#define ZIO_PIPELINE_CONTINUE 0x100 +#define ZIO_PIPELINE_STOP 0x101 + enum zio_flag { /* * Flags inherited by gang, ddt, and vdev children, diff --git a/lib/libzpool/taskq.c b/lib/libzpool/taskq.c index d63bc28e2379..72807f6a3d08 100644 --- a/lib/libzpool/taskq.c +++ b/lib/libzpool/taskq.c @@ -25,7 +25,6 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2012 Garrett D'Amore . All rights reserved. - * Copyright (c) 2014 by Delphix. All rights reserved. */ #include @@ -34,10 +33,8 @@ int taskq_now; taskq_t *system_taskq; #define TASKQ_ACTIVE 0x00010000 -#define TASKQ_NAMELEN 31 struct taskq { - char tq_name[TASKQ_NAMELEN + 1]; kmutex_t tq_lock; krwlock_t tq_threadlock; kcondvar_t tq_dispatch_cv; @@ -283,7 +280,6 @@ taskq_create(const char *name, int nthreads, pri_t pri, cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL); - (void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1); tq->tq_flags = flags | TASKQ_ACTIVE; tq->tq_active = nthreads; tq->tq_nthreads = nthreads; diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index 0bd13fd81741..6dfaf2578daa 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -671,7 +671,7 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio) return (0); } -static void +static int vdev_disk_io_start(zio_t *zio) { vdev_t *v = zio->io_vd; @@ -683,9 +683,7 @@ vdev_disk_io_start(zio_t *zio) if (!vdev_readable(v)) { zio->io_error = SET_ERROR(ENXIO); - zio_interrupt(zio); - return; - + return (ZIO_PIPELINE_CONTINUE); } switch (zio->io_cmd) { @@ -701,7 +699,7 @@ vdev_disk_io_start(zio_t *zio) error = vdev_disk_io_flush(vd->vd_bdev, zio); if (error == 0) - return; + return (ZIO_PIPELINE_STOP); zio->io_error = error; if (error == ENOTSUP) @@ -713,8 +711,8 @@ vdev_disk_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_execute(zio); - return; + return (ZIO_PIPELINE_CONTINUE); + case ZIO_TYPE_WRITE: flags = WRITE; break; @@ -725,17 +723,17 @@ vdev_disk_io_start(zio_t *zio) default: zio->io_error = SET_ERROR(ENOTSUP); - zio_interrupt(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } error = __vdev_disk_physio(vd->vd_bdev, zio, NULL, zio->io_size, zio->io_offset, flags); if (error) { zio->io_error = error; - zio_interrupt(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } + + return (ZIO_PIPELINE_STOP); } static void diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index 6420e0bc6823..296e27ebd889 100644 --- a/module/zfs/vdev_file.c +++ b/module/zfs/vdev_file.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include @@ -183,7 +183,7 @@ vdev_file_io_fsync(void *arg) zio_interrupt(zio); } -static void +static int vdev_file_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -193,8 +193,7 @@ vdev_file_io_start(zio_t *zio) /* XXPOLICY */ if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); - zio_interrupt(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } switch (zio->io_cmd) { @@ -223,12 +222,13 @@ vdev_file_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_execute(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } VERIFY3U(taskq_dispatch(vdev_file_taskq, vdev_file_io_strategy, zio, TQ_SLEEP), !=, 0); + + return (ZIO_PIPELINE_STOP); } /* ARGSUSED */ diff --git a/module/zfs/vdev_mirror.c b/module/zfs/vdev_mirror.c index 13074680dbe9..bbdf923f1692 100644 --- a/module/zfs/vdev_mirror.c +++ b/module/zfs/vdev_mirror.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include @@ -326,7 +326,7 @@ vdev_mirror_child_select(zio_t *zio) return (-1); } -static void +static int vdev_mirror_io_start(zio_t *zio) { mirror_map_t *mm; @@ -357,8 +357,7 @@ vdev_mirror_io_start(zio_t *zio) zio->io_type, zio->io_priority, 0, vdev_mirror_scrub_done, mc)); } - zio_execute(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } /* * For normal reads just pick one child. @@ -384,7 +383,7 @@ vdev_mirror_io_start(zio_t *zio) c++; } - zio_execute(zio); + return (ZIO_PIPELINE_CONTINUE); } static int diff --git a/module/zfs/vdev_missing.c b/module/zfs/vdev_missing.c index 228757334234..b9eb99d18005 100644 --- a/module/zfs/vdev_missing.c +++ b/module/zfs/vdev_missing.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ /* @@ -66,11 +66,11 @@ vdev_missing_close(vdev_t *vd) } /* ARGSUSED */ -static void +static int vdev_missing_io_start(zio_t *zio) { zio->io_error = SET_ERROR(ENOTSUP); - zio_execute(zio); + return (ZIO_PIPELINE_CONTINUE); } /* ARGSUSED */ diff --git a/module/zfs/vdev_raidz.c b/module/zfs/vdev_raidz.c index 07ddc2df63b8..bdf4171445cd 100644 --- a/module/zfs/vdev_raidz.c +++ b/module/zfs/vdev_raidz.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include @@ -1722,7 +1722,7 @@ vdev_raidz_child_done(zio_t *zio) * vdevs have had errors, then create zio read operations to the parity * columns' VDevs as well. */ -static void +static int vdev_raidz_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -1766,8 +1766,7 @@ vdev_raidz_io_start(zio_t *zio) ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL)); } - zio_execute(zio); - return; + return (ZIO_PIPELINE_CONTINUE); } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -1807,7 +1806,7 @@ vdev_raidz_io_start(zio_t *zio) } } - zio_execute(zio); + return (ZIO_PIPELINE_CONTINUE); } diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 6b0a4a58e9ab..87342090a0dc 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -59,9 +59,6 @@ kmem_cache_t *zio_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; int zio_delay_max = ZIO_DELAY_MAX; -#define ZIO_PIPELINE_CONTINUE 0x100 -#define ZIO_PIPELINE_STOP 0x101 - /* * The following actions directly effect the spa's sync-to-convergence logic. * The values below define the sync pass when we start performing the action. @@ -2611,18 +2608,6 @@ zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp) * Read and write to physical devices * ========================================================================== */ - - -/* - * Issue an I/O to the underlying vdev. Typically the issue pipeline - * stops after this stage and will resume upon I/O completion. - * However, there are instances where the vdev layer may need to - * continue the pipeline when an I/O was not issued. Since the I/O - * that was sent to the vdev layer might be different than the one - * currently active in the pipeline (see vdev_queue_io()), we explicitly - * force the underlying vdev layers to call either zio_execute() or - * zio_interrupt() to ensure that the pipeline continues with the correct I/O. - */ static int zio_vdev_io_start(zio_t *zio) { @@ -2640,8 +2625,7 @@ zio_vdev_io_start(zio_t *zio) /* * The mirror_ops handle multiple DVAs in a single BP. */ - vdev_mirror_ops.vdev_op_io_start(zio); - return (ZIO_PIPELINE_STOP); + return (vdev_mirror_ops.vdev_op_io_start(zio)); } /* @@ -2649,7 +2633,7 @@ zio_vdev_io_start(zio_t *zio) * can quickly react to certain workloads. In particular, we care * about non-scrubbing, top-level reads and writes with the following * characteristics: - * - synchronous writes of user data to non-slog devices + * - synchronous writes of user data to non-slog devices * - any reads of user data * When these conditions are met, adjust the timestamp of spa_last_io * which allows the scan thread to adjust its workload accordingly. @@ -2739,8 +2723,7 @@ zio_vdev_io_start(zio_t *zio) } } - vd->vdev_ops->vdev_op_io_start(zio); - return (ZIO_PIPELINE_STOP); + return (vd->vdev_ops->vdev_op_io_start(zio)); } static int