diff options
author | pjd <pjd@FreeBSD.org> | 2010-05-16 15:12:34 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2010-05-16 15:12:34 +0000 |
commit | eb30e42c89aa7f37d121daa051efdbc6ff771d97 (patch) | |
tree | 4cecc1f68a586e3e390b72a4ea5f321808f3da89 /sys/cddl | |
parent | 1c6b0503afe0e0b9a8b7f5fadbf8395db2dd37aa (diff) | |
download | FreeBSD-src-eb30e42c89aa7f37d121daa051efdbc6ff771d97.zip FreeBSD-src-eb30e42c89aa7f37d121daa051efdbc6ff771d97.tar.gz |
Add task structure to zio and use it instead of allocating one.
This eliminates the only place where we can sleep when calling zio_interrupt().
As a side-effect this can actually improve performance a little as we
allocate one less thing for every I/O.
Prodded by: kib
MFC after: 1 week
Diffstat (limited to 'sys/cddl')
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); } |