usr/src/uts/common/fs/zfs/vdev_queue.c
author eschrock
Fri, 03 Mar 2006 20:08:16 -0800
changeset 1544 938876158511
parent 789 b348f31ed315
child 1807 35c8b566d7af
permissions -rw-r--r--
PSARC 2006/077 zpool clear PSARC 2006/139 FMA for ZFS 6284889 arc should replace the znode cache 6333006 DMU & DSL should not panic upon I/O error 6333092 concurrent reads to a file not scaling with number of readers 6338081 ZFS/FMA phase 1 6338386 need persistent error log 6341326 i/o error causes arc buf hash table corruption 6341639 zfs backup/restore should compute/verify checksum of backup stream 6348002 out of space due to changing properties 6354724 inaccurate error message from zfs restore 6354872 dmu_sync() blows predictive accounting 6355416 zpool scrubbing consumes all memory, system hung 6363995 df should only load libzfs when it encounters a ZFS filesystem 6366320 zfs backup/restore doesn't like signals 6368892 mount -m support needed for legacy mounts 6368902 boot archive fstat support needed for ZFS Mountroot 6369424 BFU complains when bfu'ing a ZFS root filesystem 6374062 mountroot support needed for ZFS 6376356 dirtying dbuf obj=43 lvl=0 blkid=0 but not tx_held 6378391 unused members of dmu_objset_stats_t 6378392 clean up zfs_cmd_t structure 6378685 buf_init should allocate its hash table more carefully 6378976 ziltest should be a first class citizen 6381086 zdb segfaults if there is a spa deferred-free bplist 6381203 deadlock due to i/o while assigning (tc_lock held) 6381209 freed space is not immediately available 6381344 'zpool clear' 6381345 FAULTED devices should really be UNAVAIL 6381346 import should mark devices as persistently unavailable 6383272 recursive mutex_enter() during log replay with zfs root 6386326 origin property is not displayed 6386354 libzfs does too much in its _init section, calls exit(1) 6386624 zpool should not complain about non-existent devices from libdiskmgt 6386910 spa needs to be i/o error hardened 6387735 need a mechanism to inject faults into ZFS 6387736 internal ZFS utilities should be placed in an ON-private package 6389928 libzfs should ship a lint library 6390609 malformed vdev config panics on zpool_create() 6390677 version number checking makes upgrades challenging 6390713 ztest hangs in zil_suspend() 6391873 metadata compression should be turned back on 6392113 ztest sometimes reports leaked blocks because ZIL isn't resilvered 6393004 minor memory leak in unique_insert()
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/zio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/avl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * Virtual device vector for disk I/O scheduling.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
vdev_queue_deadline_compare(const void *x1, const void *x2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
	const zio_t *z1 = x1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
	const zio_t *z2 = x2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
	if (z1->io_deadline < z2->io_deadline)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
	if (z1->io_deadline > z2->io_deadline)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	if (z1->io_offset < z2->io_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
	if (z1->io_offset > z2->io_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	if (z1 < z2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	if (z1 > z2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
vdev_queue_offset_compare(const void *x1, const void *x2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	const zio_t *z1 = x1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	const zio_t *z2 = x2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	if (z1->io_offset < z2->io_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
	if (z1->io_offset > z2->io_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
	if (z1 < z2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	if (z1 > z2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
vdev_queue_init(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	vdev_queue_t *vq = &vd->vdev_queue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
	mutex_init(&vq->vq_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	avl_create(&vq->vq_deadline_tree, vdev_queue_deadline_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	    sizeof (zio_t), offsetof(struct zio, io_deadline_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
	avl_create(&vq->vq_read_tree, vdev_queue_offset_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
	    sizeof (zio_t), offsetof(struct zio, io_offset_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
	avl_create(&vq->vq_write_tree, vdev_queue_offset_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	    sizeof (zio_t), offsetof(struct zio, io_offset_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	avl_create(&vq->vq_pending_tree, vdev_queue_offset_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	    sizeof (zio_t), offsetof(struct zio, io_offset_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
vdev_queue_fini(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	vdev_queue_t *vq = &vd->vdev_queue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   105
	ASSERT(vq->vq_scrub_count == 0);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   106
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	avl_destroy(&vq->vq_deadline_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	avl_destroy(&vq->vq_read_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	avl_destroy(&vq->vq_write_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
	avl_destroy(&vq->vq_pending_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	mutex_destroy(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
static void
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   116
vdev_queue_io_add(vdev_queue_t *vq, zio_t *zio)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   117
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   118
	avl_add(&vq->vq_deadline_tree, zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   119
	avl_add(zio->io_vdev_tree, zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   120
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   121
	if ((zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   122
	    ++vq->vq_scrub_count >= vq->vq_scrub_limit)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   123
		spa_scrub_throttle(zio->io_spa, 1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   124
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   125
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   126
static void
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   127
vdev_queue_io_remove(vdev_queue_t *vq, zio_t *zio)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   128
{
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   129
	if ((zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) &&
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   130
	    vq->vq_scrub_count-- >= vq->vq_scrub_limit)
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   131
		spa_scrub_throttle(zio->io_spa, -1);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   132
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   133
	avl_remove(&vq->vq_deadline_tree, zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   134
	avl_remove(zio->io_vdev_tree, zio);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   135
}
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   136
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   137
static void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
vdev_queue_agg_io_done(zio_t *aio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	zio_t *dio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
	uint64_t offset = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	while ((dio = aio->io_delegate_list) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
		if (aio->io_type == ZIO_TYPE_READ)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
			bcopy((char *)aio->io_data + offset, dio->io_data,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
			    dio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
		offset += dio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
		aio->io_delegate_list = dio->io_delegate_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
		dio->io_delegate_next = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
		dio->io_error = aio->io_error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
		zio_next_stage(dio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
	ASSERT3U(offset, ==, aio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	zio_buf_free(aio->io_data, aio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
#define	IS_ADJACENT(io, nio) \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
	((io)->io_offset + (io)->io_size == (nio)->io_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
typedef void zio_issue_func_t(zio_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
static zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
vdev_queue_io_to_issue(vdev_queue_t *vq, uint64_t pending_limit,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
	zio_issue_func_t **funcp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	zio_t *fio, *lio, *aio, *dio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	avl_tree_t *tree;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
	uint64_t size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	ASSERT(MUTEX_HELD(&vq->vq_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	*funcp = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	if (avl_numnodes(&vq->vq_pending_tree) >= pending_limit ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	    avl_numnodes(&vq->vq_deadline_tree) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	fio = lio = avl_first(&vq->vq_deadline_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	tree = fio->io_vdev_tree;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	size = fio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
	while ((dio = AVL_PREV(tree, fio)) != NULL && IS_ADJACENT(dio, fio) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	    size + dio->io_size <= vq->vq_agg_limit) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
		dio->io_delegate_next = fio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
		fio = dio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
		size += dio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	while ((dio = AVL_NEXT(tree, lio)) != NULL && IS_ADJACENT(lio, dio) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
	    size + dio->io_size <= vq->vq_agg_limit) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
		lio->io_delegate_next = dio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
		lio = dio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
		size += dio->io_size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	if (fio != lio) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
		char *buf = zio_buf_alloc(size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
		uint64_t offset = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
		int nagg = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
		ASSERT(size <= vq->vq_agg_limit);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
		aio = zio_vdev_child_io(fio, NULL, fio->io_vd,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		    fio->io_offset, buf, size, fio->io_type,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
		    ZIO_PRIORITY_NOW, ZIO_FLAG_DONT_QUEUE |
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   208
		    ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_PROPAGATE |
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   209
		    ZIO_FLAG_NOBOOKMARK,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
		    vdev_queue_agg_io_done, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
		aio->io_delegate_list = fio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
		for (dio = fio; dio != NULL; dio = dio->io_delegate_next) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
			ASSERT(dio->io_type == aio->io_type);
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   216
			ASSERT(dio->io_vdev_tree == tree);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
			if (dio->io_type == ZIO_TYPE_WRITE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
				bcopy(dio->io_data, buf + offset, dio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
			offset += dio->io_size;
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   220
			vdev_queue_io_remove(vq, dio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
			zio_vdev_io_bypass(dio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
			nagg++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
		ASSERT(offset == size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
		dprintf("%5s  T=%llu  off=%8llx  agg=%3d  "
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
		    "old=%5llx  new=%5llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
		    zio_type_name[fio->io_type],
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		    fio->io_deadline, fio->io_offset, nagg, fio->io_size, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
		avl_add(&vq->vq_pending_tree, aio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
		*funcp = zio_nowait;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		return (aio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   238
	ASSERT(fio->io_vdev_tree == tree);
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   239
	vdev_queue_io_remove(vq, fio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	avl_add(&vq->vq_pending_tree, fio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
	*funcp = zio_next_stage;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
	return (fio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
zio_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
vdev_queue_io(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
	vdev_queue_t *vq = &zio->io_vd->vdev_queue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	zio_t *nio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
	zio_issue_func_t *func;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
	if (zio->io_flags & ZIO_FLAG_DONT_QUEUE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
		return (zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	zio->io_flags |= ZIO_FLAG_DONT_CACHE | ZIO_FLAG_DONT_QUEUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	if (zio->io_type == ZIO_TYPE_READ)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
		zio->io_vdev_tree = &vq->vq_read_tree;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
		zio->io_vdev_tree = &vq->vq_write_tree;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	mutex_enter(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	zio->io_deadline = (zio->io_timestamp >> vq->vq_time_shift) +
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	    zio->io_priority;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
   272
	vdev_queue_io_add(vq, zio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	nio = vdev_queue_io_to_issue(vq, vq->vq_min_pending, &func);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
	mutex_exit(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
	if (nio == NULL || func != zio_nowait)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		return (nio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
	func(nio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
vdev_queue_io_done(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
	vdev_queue_t *vq = &zio->io_vd->vdev_queue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
	zio_t *nio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
	zio_issue_func_t *func;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	mutex_enter(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
	avl_remove(&vq->vq_pending_tree, zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	for (i = 0; i < vq->vq_ramp_rate; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		nio = vdev_queue_io_to_issue(vq, vq->vq_max_pending, &func);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
		if (nio == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
			break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
		mutex_exit(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
		if (func == zio_next_stage)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
			zio_vdev_io_reissue(nio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
		func(nio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
		mutex_enter(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	mutex_exit(&vq->vq_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
}