FreeBSD ZFS
The Zettabyte File System
|
Virtual device read-ahead caching. More...
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/vdev_impl.h>
#include <sys/zio.h>
#include <sys/kstat.h>
Go to the source code of this file.
Data Structures | |
struct | vdc_stats |
Defines | |
#define | VCBS (1 << zfs_vdev_cache_bshift) |
#define | VDCSTAT_BUMP(stat) atomic_add_64(&vdc_stats.stat.value.ui64, 1); |
Typedefs | |
typedef struct vdc_stats | vdc_stats_t |
Functions | |
SYSCTL_DECL (_vfs_zfs_vdev) | |
SYSCTL_NODE (_vfs_zfs_vdev, OID_AUTO, cache, CTLFLAG_RW, 0,"ZFS VDEV Cache") | |
TUNABLE_INT ("vfs.zfs.vdev.cache.max",&zfs_vdev_cache_max) | |
SYSCTL_INT (_vfs_zfs_vdev_cache, OID_AUTO, max, CTLFLAG_RDTUN,&zfs_vdev_cache_max, 0,"Maximum I/O request size that increase read size") | |
TUNABLE_INT ("vfs.zfs.vdev.cache.size",&zfs_vdev_cache_size) | |
SYSCTL_INT (_vfs_zfs_vdev_cache, OID_AUTO, size, CTLFLAG_RDTUN,&zfs_vdev_cache_size, 0,"Size of VDEV cache") | |
TUNABLE_INT ("vfs.zfs.vdev.cache.bshift",&zfs_vdev_cache_bshift) | |
SYSCTL_INT (_vfs_zfs_vdev_cache, OID_AUTO, bshift, CTLFLAG_RDTUN,&zfs_vdev_cache_bshift, 0,"Turn too small requests into 1 << this value") | |
static int | vdev_cache_offset_compare (const void *a1, const void *a2) |
static int | vdev_cache_lastused_compare (const void *a1, const void *a2) |
static void | vdev_cache_evict (vdev_cache_t *vc, vdev_cache_entry_t *ve) |
Evict the specified entry from the cache. | |
static vdev_cache_entry_t * | vdev_cache_allocate (zio_t *zio) |
Allocate an entry in the cache. | |
static void | vdev_cache_hit (vdev_cache_t *vc, vdev_cache_entry_t *ve, zio_t *zio) |
static void | vdev_cache_fill (zio_t *fio) |
Fill a previously allocated cache entry with data. | |
int | vdev_cache_read (zio_t *zio) |
Read data from the cache. | |
void | vdev_cache_write (zio_t *zio) |
Update cache contents upon write completion. | |
void | vdev_cache_purge (vdev_t *vd) |
void | vdev_cache_init (vdev_t *vd) |
void | vdev_cache_fini (vdev_t *vd) |
void | vdev_cache_stat_init (void) |
void | vdev_cache_stat_fini (void) |
Variables | |
int | zfs_vdev_cache_max = 1<<14 |
All i/os smaller than zfs_vdev_cache_max will be turned into 1<<zfs_vdev_cache_bshift byte reads by the vdev_cache (aka software track buffer). | |
int | zfs_vdev_cache_size = 0 |
int | zfs_vdev_cache_bshift = 16 |
kstat_t * | vdc_ksp = NULL |
static vdc_stats_t | vdc_stats |
Virtual device read-ahead caching.
This file implements a simple LRU read-ahead cache. When the DMU reads a given block, it will often want other, nearby blocks soon thereafter. We take advantage of this by reading a larger disk region and caching the result. In the best case, this can turn 128 back-to-back 512-byte reads into a single 64k read followed by 127 cache hits; this reduces latency dramatically. In the worst case, it can turn an isolated 512-byte read into a 64k read, which doesn't affect latency all that much but is terribly wasteful of bandwidth. A more intelligent version of the cache could keep track of access patterns and not do read-ahead unless it sees at least two temporally close I/Os to the same region. Currently, only metadata I/O is inflated. A futher enhancement could take advantage of more semantic information about the I/O. And it could use something faster than an AVL tree; that was chosen solely for convenience.
There are five cache operations: allocate, fill, read, write, evict.
(1) Allocate. This reserves a cache entry for the specified region. We separate the allocate and fill operations so that multiple threads don't generate I/O for the same cache miss.
(2) Fill. When the I/O for a cache miss completes, the fill routine places the data in the previously allocated cache entry.
(3) Read. Read data from the cache.
(4) Write. Update cache contents after write completion.
(5) Evict. When allocating a new entry, we evict the oldest (LRU) entry if the total cache size exceeds zfs_vdev_cache_size.
Definition in file vdev_cache.c.
#define VCBS (1 << zfs_vdev_cache_bshift) |
Definition at line 92 of file vdev_cache.c.
#define VDCSTAT_BUMP | ( | stat | ) | atomic_add_64(&vdc_stats.stat.value.ui64, 1); |
Definition at line 120 of file vdev_cache.c.
typedef struct vdc_stats vdc_stats_t |
SYSCTL_DECL | ( | _vfs_zfs_vdev | ) |
SYSCTL_INT | ( | _vfs_zfs_vdev_cache | , |
OID_AUTO | , | ||
max | , | ||
CTLFLAG_RDTUN | , | ||
& | zfs_vdev_cache_max, | ||
0 | , | ||
"Maximum I/O request size that increase read size" | |||
) |
SYSCTL_INT | ( | _vfs_zfs_vdev_cache | , |
OID_AUTO | , | ||
bshift | , | ||
CTLFLAG_RDTUN | , | ||
& | zfs_vdev_cache_bshift, | ||
0 | , | ||
"Turn too small requests into 1 << this value" | |||
) |
SYSCTL_INT | ( | _vfs_zfs_vdev_cache | , |
OID_AUTO | , | ||
size | , | ||
CTLFLAG_RDTUN | , | ||
& | zfs_vdev_cache_size, | ||
0 | , | ||
"Size of VDEV cache" | |||
) |
SYSCTL_NODE | ( | _vfs_zfs_vdev | , |
OID_AUTO | , | ||
cache | , | ||
CTLFLAG_RW | , | ||
0 | , | ||
"ZFS VDEV Cache" | |||
) |
TUNABLE_INT | ( | "vfs.zfs.vdev.cache.size" | , |
& | zfs_vdev_cache_size | ||
) |
TUNABLE_INT | ( | "vfs.zfs.vdev.cache.max" | , |
& | zfs_vdev_cache_max | ||
) |
TUNABLE_INT | ( | "vfs.zfs.vdev.cache.bshift" | , |
& | zfs_vdev_cache_bshift | ||
) |
static vdev_cache_entry_t* vdev_cache_allocate | ( | zio_t * | zio | ) | [static] |
Allocate an entry in the cache.
At the point we don't have the data, we're just creating a placeholder so that multiple threads don't all go off and read the same blocks.
Definition at line 174 of file vdev_cache.c.
static void vdev_cache_evict | ( | vdev_cache_t * | vc, |
vdev_cache_entry_t * | ve | ||
) | [static] |
Evict the specified entry from the cache.
Definition at line 156 of file vdev_cache.c.
static void vdev_cache_fill | ( | zio_t * | fio | ) | [static] |
Fill a previously allocated cache entry with data.
Definition at line 231 of file vdev_cache.c.
void vdev_cache_fini | ( | vdev_t * | vd | ) |
Definition at line 412 of file vdev_cache.c.
static void vdev_cache_hit | ( | vdev_cache_t * | vc, |
vdev_cache_entry_t * | ve, | ||
zio_t * | zio | ||
) | [static] |
Definition at line 210 of file vdev_cache.c.
void vdev_cache_init | ( | vdev_t * | vd | ) |
Definition at line 396 of file vdev_cache.c.
static int vdev_cache_lastused_compare | ( | const void * | a1, |
const void * | a2 | ||
) | [static] |
Definition at line 136 of file vdev_cache.c.
static int vdev_cache_offset_compare | ( | const void * | a1, |
const void * | a2 | ||
) | [static] |
Definition at line 123 of file vdev_cache.c.
void vdev_cache_purge | ( | vdev_t * | vd | ) |
Definition at line 384 of file vdev_cache.c.
int vdev_cache_read | ( | zio_t * | zio | ) |
Read data from the cache.
Definition at line 271 of file vdev_cache.c.
void vdev_cache_stat_fini | ( | void | ) |
Definition at line 437 of file vdev_cache.c.
void vdev_cache_stat_init | ( | void | ) |
Definition at line 425 of file vdev_cache.c.
void vdev_cache_write | ( | zio_t * | zio | ) |
Update cache contents upon write completion.
Definition at line 348 of file vdev_cache.c.
kstat_t* vdc_ksp = NULL |
Definition at line 106 of file vdev_cache.c.
vdc_stats_t vdc_stats [static] |
{ { "delegations", KSTAT_DATA_UINT64 }, { "hits", KSTAT_DATA_UINT64 }, { "misses", KSTAT_DATA_UINT64 } }
Definition at line 114 of file vdev_cache.c.