Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Illumos #5244 zio pipeline callers should explicitly invoke next stage #2828

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sys/vdev_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 int vdev_io_start_func_t(zio_t *zio);
typedef void 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);
Expand Down
3 changes: 0 additions & 3 deletions include/sys/zio.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,6 @@ 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,
Expand Down
4 changes: 4 additions & 0 deletions lib/libzpool/taskq.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
* Copyright (c) 2014 by Delphix. All rights reserved.
*/

#include <sys/zfs_context.h>
Expand All @@ -33,8 +34,10 @@ 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;
Expand Down Expand Up @@ -280,6 +283,7 @@ 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;
Expand Down
20 changes: 11 additions & 9 deletions module/zfs/vdev_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
return (0);
}

static int
static void
vdev_disk_io_start(zio_t *zio)
{
vdev_t *v = zio->io_vd;
Expand All @@ -669,7 +669,9 @@ vdev_disk_io_start(zio_t *zio)

if (!vdev_readable(v)) {
zio->io_error = SET_ERROR(ENXIO);
return (ZIO_PIPELINE_CONTINUE);
zio_interrupt(zio);
return;

}

switch (zio->io_cmd) {
Expand All @@ -685,7 +687,7 @@ vdev_disk_io_start(zio_t *zio)

error = vdev_disk_io_flush(vd->vd_bdev, zio);
if (error == 0)
return (ZIO_PIPELINE_STOP);
return;

zio->io_error = error;
if (error == ENOTSUP)
Expand All @@ -697,8 +699,8 @@ vdev_disk_io_start(zio_t *zio)
zio->io_error = SET_ERROR(ENOTSUP);
}

return (ZIO_PIPELINE_CONTINUE);

zio_execute(zio);
return;
case ZIO_TYPE_WRITE:
flags = WRITE;
break;
Expand All @@ -709,17 +711,17 @@ vdev_disk_io_start(zio_t *zio)

default:
zio->io_error = SET_ERROR(ENOTSUP);
return (ZIO_PIPELINE_CONTINUE);
zio_interrupt(zio);
return;
}

error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
zio->io_size, zio->io_offset, flags);
if (error) {
zio->io_error = error;
return (ZIO_PIPELINE_CONTINUE);
zio_interrupt(zio);
return;
}

return (ZIO_PIPELINE_STOP);
}

static void
Expand Down
14 changes: 7 additions & 7 deletions module/zfs/vdev_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
*/

#include <sys/zfs_context.h>
Expand Down Expand Up @@ -172,7 +172,7 @@ vdev_file_io_fsync(void *arg)
zio_interrupt(zio);
}

static int
static void
vdev_file_io_start(zio_t *zio)
{
vdev_t *vd = zio->io_vd;
Expand All @@ -182,7 +182,8 @@ vdev_file_io_start(zio_t *zio)
/* XXPOLICY */
if (!vdev_readable(vd)) {
zio->io_error = SET_ERROR(ENXIO);
return (ZIO_PIPELINE_CONTINUE);
zio_interrupt(zio);
return;
}

switch (zio->io_cmd) {
Expand All @@ -201,7 +202,7 @@ vdev_file_io_start(zio_t *zio)
if (spl_fstrans_check()) {
VERIFY3U(taskq_dispatch(vdev_file_taskq,
vdev_file_io_fsync, zio, TQ_SLEEP), !=, 0);
return (ZIO_PIPELINE_STOP);
return;
}

zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC,
Expand All @@ -211,13 +212,12 @@ vdev_file_io_start(zio_t *zio)
zio->io_error = SET_ERROR(ENOTSUP);
}

return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
return;
}

VERIFY3U(taskq_dispatch(vdev_file_taskq, vdev_file_io_strategy, zio,
TQ_SLEEP), !=, 0);

return (ZIO_PIPELINE_STOP);
}

/* ARGSUSED */
Expand Down
9 changes: 5 additions & 4 deletions module/zfs/vdev_mirror.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/

/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
*/

#include <sys/zfs_context.h>
Expand Down Expand Up @@ -327,7 +327,7 @@ vdev_mirror_child_select(zio_t *zio)
return (-1);
}

static int
static void
vdev_mirror_io_start(zio_t *zio)
{
mirror_map_t *mm;
Expand All @@ -352,7 +352,8 @@ vdev_mirror_io_start(zio_t *zio)
zio->io_type, zio->io_priority, 0,
vdev_mirror_scrub_done, mc));
}
return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
return;
}
/*
* For normal reads just pick one child.
Expand All @@ -378,7 +379,7 @@ vdev_mirror_io_start(zio_t *zio)
c++;
}

return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
}

static int
Expand Down
6 changes: 3 additions & 3 deletions module/zfs/vdev_missing.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*/

/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
*/

/*
Expand Down Expand Up @@ -66,11 +66,11 @@ vdev_missing_close(vdev_t *vd)
}

/* ARGSUSED */
static int
static void
vdev_missing_io_start(zio_t *zio)
{
zio->io_error = SET_ERROR(ENOTSUP);
return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
}

/* ARGSUSED */
Expand Down
9 changes: 5 additions & 4 deletions module/zfs/vdev_raidz.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
*/

#include <sys/zfs_context.h>
Expand Down Expand Up @@ -1567,7 +1567,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 int
static void
vdev_raidz_io_start(zio_t *zio)
{
vdev_t *vd = zio->io_vd;
Expand Down Expand Up @@ -1611,7 +1611,8 @@ vdev_raidz_io_start(zio_t *zio)
ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL));
}

return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
return;
}

ASSERT(zio->io_type == ZIO_TYPE_READ);
Expand Down Expand Up @@ -1651,7 +1652,7 @@ vdev_raidz_io_start(zio_t *zio)
}
}

return (ZIO_PIPELINE_CONTINUE);
zio_execute(zio);
}


Expand Down
23 changes: 20 additions & 3 deletions module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ 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.
Expand Down Expand Up @@ -2526,6 +2529,18 @@ 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)
{
Expand All @@ -2543,15 +2558,16 @@ zio_vdev_io_start(zio_t *zio)
/*
* The mirror_ops handle multiple DVAs in a single BP.
*/
return (vdev_mirror_ops.vdev_op_io_start(zio));
vdev_mirror_ops.vdev_op_io_start(zio);
return (ZIO_PIPELINE_STOP);
}

/*
* We keep track of time-sensitive I/Os so that the scan thread
* 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.
Expand Down Expand Up @@ -2637,7 +2653,8 @@ zio_vdev_io_start(zio_t *zio)
}
}

return (vd->vdev_ops->vdev_op_io_start(zio));
vd->vdev_ops->vdev_op_io_start(zio);
return (ZIO_PIPELINE_STOP);
}

static int
Expand Down