FreeBSD ZFS
The Zettabyte File System
Data Structures | Defines | Typedefs | Functions | Variables

vdev_cache.c File Reference

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>
Include dependency graph for vdev_cache.c:

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_tvdev_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

Detailed Description

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 Documentation

#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 Documentation

typedef struct vdc_stats vdc_stats_t

Function Documentation

SYSCTL_DECL ( _vfs_zfs_vdev  )
SYSCTL_INT ( _vfs_zfs_vdev_cache  ,
OID_AUTO  ,
max  ,
CTLFLAG_RDTUN  ,
zfs_vdev_cache_max,
,
"Maximum I/O request size that increase read size"   
)
SYSCTL_INT ( _vfs_zfs_vdev_cache  ,
OID_AUTO  ,
bshift  ,
CTLFLAG_RDTUN  ,
zfs_vdev_cache_bshift,
,
"Turn too small requests into 1 << this value"   
)
SYSCTL_INT ( _vfs_zfs_vdev_cache  ,
OID_AUTO  ,
size  ,
CTLFLAG_RDTUN  ,
zfs_vdev_cache_size,
,
"Size of VDEV cache"   
)
SYSCTL_NODE ( _vfs_zfs_vdev  ,
OID_AUTO  ,
cache  ,
CTLFLAG_RW  ,
,
"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.

Returns:
0 on cache hit, errno on a miss.

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.


Variable Documentation

kstat_t* vdc_ksp = NULL

Definition at line 106 of file vdev_cache.c.

Initial value:
 {
        { "delegations",        KSTAT_DATA_UINT64 },
        { "hits",               KSTAT_DATA_UINT64 },
        { "misses",             KSTAT_DATA_UINT64 }
}

Definition at line 114 of file vdev_cache.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines