Skip to content

Commit

Permalink
add prefetch property
Browse files Browse the repository at this point in the history
ZFS prefetch is currently governed by the zfs_prefetch_disable
tunable. However, this is a module-wide settings - if a specific
dataset benefits from prefetch, while others have issue with it,
an optimal solution does not exists.

This commit introduce the "prefetch" tri-state property, which enable
granular control (at dataset/volume level) for prefetching.

This patch does not remove the zfs_prefetch_disable, which reimains
a system-wide switch for enable/disable prefetch. However, to avoid
duplication, it would be preferable to deprecate and then remove
the module tunable.

Please note that during pool import, os_prefetch defaults to 0.
For this reason ZFS_PREFETCH_ALL was enumerated as 0, otherwise
prefetch would be disabled for pool import (causing slower import).

Signed-off-by: Gionatan Danti <[email protected]>
  • Loading branch information
shodanshok committed Sep 5, 2023
1 parent 95f71c0 commit c1246fe
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 1 deletion.
3 changes: 3 additions & 0 deletions include/sys/dmu_objset.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ struct objset {
dmu_objset_upgrade_cb_t os_upgrade_cb;
boolean_t os_upgrade_exit;
int os_upgrade_status;

/* prefetch */
zfs_prefetch_type_t os_prefetch;
};

#define DMU_META_OBJSET 0
Expand Down
7 changes: 7 additions & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ typedef enum {
ZFS_PROP_REDACTED,
ZFS_PROP_REDACT_SNAPS,
ZFS_PROP_SNAPSHOTS_CHANGED,
ZFS_PROP_PREFETCH,
ZFS_NUM_PROPS
} zfs_prop_t;

Expand Down Expand Up @@ -543,6 +544,12 @@ typedef enum zfs_key_location {
ZFS_KEYLOCATION_LOCATIONS
} zfs_keylocation_t;

typedef enum {
ZFS_PREFETCH_ALL = 0,
ZFS_PREFETCH_METADATA = 1,
ZFS_PREFETCH_NONE = 2
} zfs_prefetch_type_t;

#define DEFAULT_PBKDF2_ITERATIONS 350000
#define MIN_PBKDF2_ITERATIONS 100000

Expand Down
11 changes: 11 additions & 0 deletions module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,13 @@ zfs_prop_init(void)
{ NULL }
};

static const zprop_index_t prefetch_table[] = {
{ "all", ZFS_PREFETCH_ALL },
{ "metadata", ZFS_PREFETCH_METADATA },
{ "none", ZFS_PREFETCH_NONE },
{ NULL }
};

struct zfs_mod_supported_features *sfeatures =
zfs_mod_list_supported(ZFS_SYSFS_DATASET_PROPERTIES);

Expand Down Expand Up @@ -468,6 +475,10 @@ zfs_prop_init(void)
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"default | full | geom | dev | none", "VOLMODE", volmode_table,
sfeatures);
zprop_register_index(ZFS_PROP_PREFETCH, "prefetch",
ZFS_PREFETCH_ALL, PROP_INHERIT,

Check failure on line 479 in module/zcommon/zfs_prop.c

View workflow job for this annotation

GitHub Actions / checkstyle

space or tab at end of line
ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT | ZFS_TYPE_VOLUME,
"all | metadata | none", "PREFETCH", prefetch_table, sfeatures);

/* inherit index (boolean) properties */
zprop_register_index(ZFS_PROP_ATIME, "atime", 1, PROP_INHERIT,
Expand Down
18 changes: 18 additions & 0 deletions module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,19 @@ secondary_cache_changed_cb(void *arg, uint64_t newval)
os->os_secondary_cache = newval;
}

static void
prefetch_changed_cb(void *arg, uint64_t newval)
{
objset_t *os = arg;

/*
* Inheritance should have been done by now.
*/
ASSERT(newval == ZFS_PREFETCH_ALL || newval == ZFS_PREFETCH_NONE ||
newval == ZFS_PREFETCH_METADATA);
os->os_prefetch = newval;
}

static void
sync_changed_cb(void *arg, uint64_t newval)
{
Expand Down Expand Up @@ -562,6 +575,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp,
zfs_prop_to_name(ZFS_PROP_SECONDARYCACHE),
secondary_cache_changed_cb, os);
}
if (err == 0) {
err = dsl_prop_register(ds,
zfs_prop_to_name(ZFS_PROP_PREFETCH),
prefetch_changed_cb, os);
}
if (!ds->ds_is_snapshot) {
if (err == 0) {
err = dsl_prop_register(ds,
Expand Down
7 changes: 6 additions & 1 deletion module/zfs/dmu_zfetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,14 @@ dmu_zfetch_prepare(zfetch_t *zf, uint64_t blkid, uint64_t nblks,
{
zstream_t *zs;
spa_t *spa = zf->zf_dnode->dn_objset->os_spa;
zfs_prefetch_type_t os_prefetch = zf->zf_dnode->dn_objset->os_prefetch;

if (zfs_prefetch_disable)
if (zfs_prefetch_disable || os_prefetch == ZFS_PREFETCH_NONE)
return (NULL);

if (os_prefetch == ZFS_PREFETCH_METADATA)
fetch_data = B_FALSE;

/*
* If we haven't yet loaded the indirect vdevs' mappings, we
* can only read from blocks that we carefully ensure are on
Expand Down

0 comments on commit c1246fe

Please sign in to comment.