usr/src/uts/common/fs/zfs/vdev_cache.c
author Chris Kirby <Chris.Kirby@oracle.com>
Thu, 10 Jun 2010 15:46:47 -0600
changeset 12605 6790e683d5a5
parent 11066 cebb50cbe4f9
child 13346 f3ce1af7c12d
permissions -rw-r--r--
6959846 DMU traverse prefetch size should be a global tunable
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
/*
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
    22
 * Copyright 2009 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
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <sys/vdev_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/zio.h>
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    30
#include <sys/kstat.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
 * Virtual device read-ahead caching.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
 * This file implements a simple LRU read-ahead cache.  When the DMU reads
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
 * a given block, it will often want other, nearby blocks soon thereafter.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
 * We take advantage of this by reading a larger disk region and caching
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    38
 * the result.  In the best case, this can turn 128 back-to-back 512-byte
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    39
 * reads into a single 64k read followed by 127 cache hits; this reduces
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
 * latency dramatically.  In the worst case, it can turn an isolated 512-byte
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    41
 * read into a 64k read, which doesn't affect latency all that much but is
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
 * terribly wasteful of bandwidth.  A more intelligent version of the cache
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
 * could keep track of access patterns and not do read-ahead unless it sees
4634
39bfb9e90d34 6437054 vdev_cache wises up: increase DB performance by 16%
ek110237
parents: 4451
diff changeset
    44
 * at least two temporally close I/Os to the same region.  Currently, only
39bfb9e90d34 6437054 vdev_cache wises up: increase DB performance by 16%
ek110237
parents: 4451
diff changeset
    45
 * metadata I/O is inflated.  A futher enhancement could take advantage of
39bfb9e90d34 6437054 vdev_cache wises up: increase DB performance by 16%
ek110237
parents: 4451
diff changeset
    46
 * more semantic information about the I/O.  And it could use something
39bfb9e90d34 6437054 vdev_cache wises up: increase DB performance by 16%
ek110237
parents: 4451
diff changeset
    47
 * faster than an AVL tree; that was chosen solely for convenience.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
 * There are five cache operations: allocate, fill, read, write, evict.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
 * (1) Allocate.  This reserves a cache entry for the specified region.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
 *     We separate the allocate and fill operations so that multiple threads
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
 *     don't generate I/O for the same cache miss.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
 * (2) Fill.  When the I/O for a cache miss completes, the fill routine
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
 *     places the data in the previously allocated cache entry.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
 * (3) Read.  Read data from the cache.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
 * (4) Write.  Update cache contents after write completion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
 * (5) Evict.  When allocating a new entry, we evict the oldest (LRU) entry
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    63
 *     if the total cache size exceeds zfs_vdev_cache_size.
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    64
 */
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    65
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    66
/*
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    67
 * These tunables are for performance analysis.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
 */
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    69
/*
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    70
 * All i/os smaller than zfs_vdev_cache_max will be turned into
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    71
 * 1<<zfs_vdev_cache_bshift byte reads by the vdev_cache (aka software
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    72
 * track buffer).  At most zfs_vdev_cache_size bytes will be kept in each
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    73
 * vdev's vdev_cache.
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    74
 */
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    75
int zfs_vdev_cache_max = 1<<14;			/* 16KB */
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    76
int zfs_vdev_cache_size = 10ULL << 20;		/* 10MB */
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    77
int zfs_vdev_cache_bshift = 16;
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
    78
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    79
#define	VCBS (1 << zfs_vdev_cache_bshift)	/* 64KB */
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    80
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    81
kstat_t	*vdc_ksp = NULL;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    82
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    83
typedef struct vdc_stats {
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    84
	kstat_named_t vdc_stat_delegations;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    85
	kstat_named_t vdc_stat_hits;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    86
	kstat_named_t vdc_stat_misses;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    87
} vdc_stats_t;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    88
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    89
static vdc_stats_t vdc_stats = {
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    90
	{ "delegations",	KSTAT_DATA_UINT64 },
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    91
	{ "hits",		KSTAT_DATA_UINT64 },
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    92
	{ "misses",		KSTAT_DATA_UINT64 }
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    93
};
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    94
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
    95
#define	VDCSTAT_BUMP(stat)	atomic_add_64(&vdc_stats.stat.value.ui64, 1);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
vdev_cache_offset_compare(const void *a1, const void *a2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	const vdev_cache_entry_t *ve1 = a1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	const vdev_cache_entry_t *ve2 = a2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	if (ve1->ve_offset < ve2->ve_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
	if (ve1->ve_offset > ve2->ve_offset)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
vdev_cache_lastused_compare(const void *a1, const void *a2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
	const vdev_cache_entry_t *ve1 = a1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
	const vdev_cache_entry_t *ve2 = a2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	if (ve1->ve_lastused < ve2->ve_lastused)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
	if (ve1->ve_lastused > ve2->ve_lastused)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
	 * Among equally old entries, sort by offset to ensure uniqueness.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	return (vdev_cache_offset_compare(a1, a2));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
 * Evict the specified entry from the cache.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
vdev_cache_evict(vdev_cache_t *vc, vdev_cache_entry_t *ve)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	ASSERT(MUTEX_HELD(&vc->vc_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	ASSERT(ve->ve_fill_io == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	ASSERT(ve->ve_data != NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	avl_remove(&vc->vc_lastused_tree, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	avl_remove(&vc->vc_offset_tree, ve);
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   139
	zio_buf_free(ve->ve_data, VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	kmem_free(ve, sizeof (vdev_cache_entry_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
 * Allocate an entry in the cache.  At the point we don't have the data,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
 * we're just creating a placeholder so that multiple threads don't all
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
 * go off and read the same blocks.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
static vdev_cache_entry_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
vdev_cache_allocate(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   152
	uint64_t offset = P2ALIGN(zio->io_offset, VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
	vdev_cache_entry_t *ve;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	ASSERT(MUTEX_HELD(&vc->vc_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   157
	if (zfs_vdev_cache_size == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
		return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
	 * If adding a new entry would exceed the cache size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	 * evict the oldest entry (LRU).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
	 */
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   164
	if ((avl_numnodes(&vc->vc_lastused_tree) << zfs_vdev_cache_bshift) >
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   165
	    zfs_vdev_cache_size) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
		ve = avl_first(&vc->vc_lastused_tree);
7754
b80e4842ad54 6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 5810
diff changeset
   167
		if (ve->ve_fill_io != NULL)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
			return (NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
		ASSERT(ve->ve_hits != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
		vdev_cache_evict(vc, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	ve = kmem_zalloc(sizeof (vdev_cache_entry_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	ve->ve_offset = offset;
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 8632
diff changeset
   175
	ve->ve_lastused = ddi_get_lbolt();
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   176
	ve->ve_data = zio_buf_alloc(VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	avl_add(&vc->vc_offset_tree, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	avl_add(&vc->vc_lastused_tree, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
	return (ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
vdev_cache_hit(vdev_cache_t *vc, vdev_cache_entry_t *ve, zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
{
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   187
	uint64_t cache_phase = P2PHASE(zio->io_offset, VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	ASSERT(MUTEX_HELD(&vc->vc_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	ASSERT(ve->ve_fill_io == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 8632
diff changeset
   192
	if (ve->ve_lastused != ddi_get_lbolt()) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
		avl_remove(&vc->vc_lastused_tree, ve);
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 8632
diff changeset
   194
		ve->ve_lastused = ddi_get_lbolt();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
		avl_add(&vc->vc_lastused_tree, ve);
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
	ve->ve_hits++;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	bcopy(ve->ve_data + cache_phase, zio->io_data, zio->io_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
 * Fill a previously allocated cache entry with data.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
static void
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   206
vdev_cache_fill(zio_t *fio)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
{
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   208
	vdev_t *vd = fio->io_vd;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
	vdev_cache_t *vc = &vd->vdev_cache;
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   210
	vdev_cache_entry_t *ve = fio->io_private;
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   211
	zio_t *pio;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   213
	ASSERT(fio->io_size == VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	 * Add data to the cache.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
	mutex_enter(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   220
	ASSERT(ve->ve_fill_io == fio);
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   221
	ASSERT(ve->ve_offset == fio->io_offset);
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   222
	ASSERT(ve->ve_data == fio->io_data);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	ve->ve_fill_io = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	 * Even if this cache line was invalidated by a missed write update,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	 * any reads that were queued up before the missed update are still
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
	 * valid, so we can satisfy them from this line before we evict it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
	 */
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   231
	while ((pio = zio_walk_parents(fio)) != NULL)
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   232
		vdev_cache_hit(vc, ve, pio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   234
	if (fio->io_error || ve->ve_missed_update)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		vdev_cache_evict(vc, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
	mutex_exit(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
 * Read data from the cache.  Returns 0 on cache hit, errno on a miss.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
vdev_cache_read(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	vdev_cache_entry_t *ve, ve_search;
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   248
	uint64_t cache_offset = P2ALIGN(zio->io_offset, VCBS);
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   249
	uint64_t cache_phase = P2PHASE(zio->io_offset, VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
	zio_t *fio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
	ASSERT(zio->io_type == ZIO_TYPE_READ);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
	if (zio->io_flags & ZIO_FLAG_DONT_CACHE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   257
	if (zio->io_size > zfs_vdev_cache_max)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
		return (EOVERFLOW);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
	 * If the I/O straddles two or more cache blocks, don't cache it.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	 */
7837
001de5627df3 6333409 traversal code should be able to issue multiple reads in parallel
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents: 7754
diff changeset
   263
	if (P2BOUNDARY(zio->io_offset, zio->io_size, VCBS))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
		return (EXDEV);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   266
	ASSERT(cache_phase + zio->io_size <= VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
	mutex_enter(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	ve_search.ve_offset = cache_offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
	ve = avl_find(&vc->vc_offset_tree, &ve_search, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
	if (ve != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
		if (ve->ve_missed_update) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
			mutex_exit(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
			return (ESTALE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
		if ((fio = ve->ve_fill_io) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
			zio_vdev_io_bypass(zio);
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   281
			zio_add_child(zio, fio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
			mutex_exit(&vc->vc_lock);
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   283
			VDCSTAT_BUMP(vdc_stat_delegations);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
		vdev_cache_hit(vc, ve, zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
		zio_vdev_io_bypass(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
		mutex_exit(&vc->vc_lock);
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   291
		VDCSTAT_BUMP(vdc_stat_hits);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
		return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
	ve = vdev_cache_allocate(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	if (ve == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
		mutex_exit(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
		return (ENOMEM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
7754
b80e4842ad54 6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 5810
diff changeset
   302
	fio = zio_vdev_delegated_io(zio->io_vd, cache_offset,
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   303
	    ve->ve_data, VCBS, ZIO_TYPE_READ, ZIO_PRIORITY_CACHE_FILL,
7754
b80e4842ad54 6754011 SPA 3.0: lock breakup, i/o pipeline refactoring, device failure handling
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 5810
diff changeset
   304
	    ZIO_FLAG_DONT_CACHE, vdev_cache_fill, ve);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
	ve->ve_fill_io = fio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	zio_vdev_io_bypass(zio);
8632
36ef517870a3 6798384 It can take a village to raise a zio
Bill Moore <Bill.Moore@Sun.COM>
parents: 7837
diff changeset
   308
	zio_add_child(zio, fio);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	mutex_exit(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	zio_nowait(fio);
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   312
	VDCSTAT_BUMP(vdc_stat_misses);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
 * Update cache contents upon write completion.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
vdev_cache_write(zio_t *zio)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	vdev_cache_t *vc = &zio->io_vd->vdev_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	vdev_cache_entry_t *ve, ve_search;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
	uint64_t io_start = zio->io_offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	uint64_t io_end = io_start + zio->io_size;
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   327
	uint64_t min_offset = P2ALIGN(io_start, VCBS);
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   328
	uint64_t max_offset = P2ROUNDUP(io_end, VCBS);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	avl_index_t where;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	ASSERT(zio->io_type == ZIO_TYPE_WRITE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	mutex_enter(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	ve_search.ve_offset = min_offset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	ve = avl_find(&vc->vc_offset_tree, &ve_search, &where);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	if (ve == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
		ve = avl_nearest(&vc->vc_offset_tree, where, AVL_AFTER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
	while (ve != NULL && ve->ve_offset < max_offset) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		uint64_t start = MAX(ve->ve_offset, io_start);
3059
7d69dbccfcbb 6472021 vdev knobs can not be turned
ahrens
parents: 1544
diff changeset
   343
		uint64_t end = MIN(ve->ve_offset + VCBS, io_end);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
		if (ve->ve_fill_io != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
			ve->ve_missed_update = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
			bcopy((char *)zio->io_data + start - io_start,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
			    ve->ve_data + start - ve->ve_offset, end - start);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
		ve = AVL_NEXT(&vc->vc_offset_tree, ve);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	mutex_exit(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
void
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   357
vdev_cache_purge(vdev_t *vd)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   358
{
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   359
	vdev_cache_t *vc = &vd->vdev_cache;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   360
	vdev_cache_entry_t *ve;
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   361
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   362
	mutex_enter(&vc->vc_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   363
	while ((ve = avl_first(&vc->vc_offset_tree)) != NULL)
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   364
		vdev_cache_evict(vc, ve);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   365
	mutex_exit(&vc->vc_lock);
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   366
}
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   367
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   368
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
vdev_cache_init(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	vdev_cache_t *vc = &vd->vdev_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	mutex_init(&vc->vc_lock, NULL, MUTEX_DEFAULT, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
	avl_create(&vc->vc_offset_tree, vdev_cache_offset_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
	    sizeof (vdev_cache_entry_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
	    offsetof(struct vdev_cache_entry, ve_offset_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
	avl_create(&vc->vc_lastused_tree, vdev_cache_lastused_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	    sizeof (vdev_cache_entry_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
	    offsetof(struct vdev_cache_entry, ve_lastused_node));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
vdev_cache_fini(vdev_t *vd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
	vdev_cache_t *vc = &vd->vdev_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
4451
24fbf2d7a5d7 PSARC 2007/197 ZFS hotplug
eschrock
parents: 3059
diff changeset
   389
	vdev_cache_purge(vd);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	avl_destroy(&vc->vc_offset_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
	avl_destroy(&vc->vc_lastused_tree);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	mutex_destroy(&vc->vc_lock);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
}
5810
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   396
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   397
void
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   398
vdev_cache_stat_init(void)
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   399
{
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   400
	vdc_ksp = kstat_create("zfs", 0, "vdev_cache_stats", "misc",
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   401
	    KSTAT_TYPE_NAMED, sizeof (vdc_stats) / sizeof (kstat_named_t),
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   402
	    KSTAT_FLAG_VIRTUAL);
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   403
	if (vdc_ksp != NULL) {
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   404
		vdc_ksp->ks_data = &vdc_stats;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   405
		kstat_install(vdc_ksp);
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   406
	}
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   407
}
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   408
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   409
void
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   410
vdev_cache_stat_fini(void)
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   411
{
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   412
	if (vdc_ksp != NULL) {
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   413
		kstat_delete(vdc_ksp);
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   414
		vdc_ksp = NULL;
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   415
	}
9253e5eac38c 6649150 add kstats to the vdev cache
ek110237
parents: 5530
diff changeset
   416
}