diff options
4 files changed, 80 insertions, 10 deletions
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c index 1e3b1ef..29bcd31 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c @@ -40,12 +40,6 @@ __FBSDID("$FreeBSD$"); static uma_zone_t taskq_zone; -struct ostask { - struct task ost_task; - task_func_t *ost_func; - void *ost_arg; -}; - taskq_t *system_taskq = NULL; static void @@ -140,3 +134,32 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags) return ((taskqid_t)(void *)task); } + +#define TASKQ_MAGIC 0x74541c + +static void +taskq_run_safe(void *arg, int pending __unused) +{ + struct ostask *task = arg; + + ASSERT(task->ost_magic == TASKQ_MAGIC); + task->ost_func(task->ost_arg); + task->ost_magic = 0; +} + +taskqid_t +taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg, + struct ostask *task) +{ + + ASSERT(task->ost_magic != TASKQ_MAGIC); + + task->ost_magic = TASKQ_MAGIC; + task->ost_func = func; + task->ost_arg = arg; + + TASK_INIT(&task->ost_task, 0, taskq_run_safe, task); + taskqueue_enqueue(tq->tq_queue, &task->ost_task); + + return ((taskqid_t)(void *)task); +} diff --git a/sys/cddl/compat/opensolaris/sys/taskq.h b/sys/cddl/compat/opensolaris/sys/taskq.h new file mode 100644 index 0000000..9083e6a --- /dev/null +++ b/sys/cddl/compat/opensolaris/sys/taskq.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _OPENSOLARIS_SYS_TASKQ_H_ +#define _OPENSOLARIS_SYS_TASKQ_H_ + +#include_next <sys/taskq.h> + +struct ostask { + struct task ost_task; + task_func_t *ost_func; + void *ost_arg; + int ost_magic; +}; + +taskqid_t taskq_dispatch_safe(taskq_t *tq, task_func_t func, void *arg, + struct ostask *task); + +#endif /* _OPENSOLARIS_SYS_TASKQ_H_ */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index fbc8c45..f61ca89 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -316,6 +316,9 @@ struct zio { /* FMA state */ uint64_t io_ena; + + /* FreeBSD only. */ + struct ostask io_task; }; extern zio_t *zio_null(zio_t *pio, spa_t *spa, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index e7227f2..7f5416d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -908,8 +908,8 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q) if (t == ZIO_TYPE_WRITE && zio->io_vd && zio->io_vd->vdev_aux) t = ZIO_TYPE_NULL; - (void) taskq_dispatch(zio->io_spa->spa_zio_taskq[t][q], - (task_func_t *)zio_execute, zio, TQ_SLEEP); + (void) taskq_dispatch_safe(zio->io_spa->spa_zio_taskq[t][q], + (task_func_t *)zio_execute, zio, &zio->io_task); } static boolean_t @@ -2220,9 +2220,9 @@ zio_done(zio_t *zio) * Reexecution is potentially a huge amount of work. * Hand it off to the otherwise-unused claim taskq. */ - (void) taskq_dispatch( + (void) taskq_dispatch_safe( spa->spa_zio_taskq[ZIO_TYPE_CLAIM][ZIO_TASKQ_ISSUE], - (task_func_t *)zio_reexecute, zio, TQ_SLEEP); + (task_func_t *)zio_reexecute, zio, &zio->io_task); } return (ZIO_PIPELINE_STOP); } |