Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add prefetch property #15237

Closed
wants to merge 2 commits into from
Closed

add prefetch property #15237

wants to merge 2 commits into from

Conversation

shodanshok
Copy link
Contributor

@shodanshok shodanshok commented Sep 3, 2023

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.

Motivation and Context

Description

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Performance enhancement (non-breaking change which improves efficiency)
  • Code cleanup (non-breaking change which makes code smaller or more readable)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Library ABI change (libzfs, libzfs_core, libnvpair, libuutil and libzfsbootenv)
  • Documentation (a change to man pages or other documentation)

Checklist:

@shodanshok shodanshok force-pushed the master branch 3 times, most recently from df270ba to 0c75753 Compare September 3, 2023 11:46
@gmelikov
Copy link
Member

gmelikov commented Sep 3, 2023

What's with backward compatibility - i.e. import pool with such defined property with pre-patch code?

@shodanshok
Copy link
Contributor Author

shodanshok commented Sep 3, 2023

What's with backward compatibility - i.e. import pool with such defined property with pre-patch code?

Good question. An unpatched ZFS seems to have no issue importing and using the pool - the prefetch property is simply ignored.

# patched (2.2 master)
root@debian12:~/zfs/zfs# zpool import tank
root@debian12:~/zfs/zfs# dmesg
[ 2174.204782] ZFS: Loaded module v2.2.99-1, ZFS pool version 5000, ZFS filesystem version 5
root@debian12:~/zfs/zfs# md5sum /tank/test/test.img
a7c960320c0ccac4b9879af3067d0bd2  /tank/test/test.img

# unpatched code (2.1.12)
root@debian12:~/zfs/zfs-2.1.12# zpool import tank
root@debian12:~/zfs/zfs-2.1.12# dmesg
[ 1640.430596] ZFS: Loaded module v2.1.12-1, ZFS pool version 5000, ZFS filesystem version 5
root@debian12:~/zfs/zfs-2.1.12# md5sum /tank/test/test.img
a7c960320c0ccac4b9879af3067d0bd2  /tank/test/test.img

Copy link
Member

@amotin amotin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no objections besides minor comments above and the fact that I don't like manual tuning for things that should behave out of the box. From time to time I think if we could properly wire POSIX fadvise API to allow applications to control prefetch.

I wonder, do you have particular workloads where prefetcher is hurting? Can prefetcher be improved to handle them better?

include/sys/dmu_objset.h Outdated Show resolved Hide resolved
include/sys/dmu_objset.h Outdated Show resolved Hide resolved
@shodanshok
Copy link
Contributor Author

From time to time I think if we could properly wire POSIX fadvise API to allow applications to control prefetch.

Yeah, adding fadvise would be great. However, for these (many) applications not using it, manual prefetch control is useful.

I wonder, do you have particular workloads where prefetcher is hurting? Can prefetcher be improved to handle them better?

To tell the truth, no, it always worked well for me (or at least not so bad I noticed). However, it seems others have issues with it (see #15214) and I think it would be useful to let prefetch be a dataset property, so to be selectively disabled on the specific datasets/workloads were it cause issue (leaving the other with prefetch enabled).

Any feeling on (eventually) removing the module tunable? Thanks.

@rincebrain
Copy link
Contributor

My only thought would be wanting to tune metadata versus data prefetch versus none at all, but I have no workloads that this impacts, so I have no suggestions about how much it matters...

@shodanshok
Copy link
Contributor Author

shodanshok commented Sep 5, 2023

My only thought would be wanting to tune metadata versus data prefetch versus none at all, but I have no workloads that this impacts, so I have no suggestions about how much it matters...

Do you think something as prefetch = none | metadata | all would be preferable? Or metadata should always be prefetched, even if prefetch = off?

@amotin
Copy link
Member

amotin commented Sep 5, 2023

Tri-state switch would be more functional. In support of metadata prefetch, we are now prefetching indirect blocks for write, and I remember when I implemented it it did improve write speeds by not delaying them while trying to read the indirect from pool already busy by async writes.

Speaking about terminology though, ZFS has two independent types of prefetch: prescient and speculative, and the parameter control only the last, while may be interpreted differently. Setting it to metadata could be interpreted as prefetching indirect blocks for data accesses, or all metadata accesses including L0. Just a thoughts.

@shodanshok
Copy link
Contributor Author

Tri-state switch would be more functional.

Ok, I'll try to implement it.

Speaking about terminology though, ZFS has two independent types of prefetch: prescient and speculative, and the parameter control only the last

Sure, prescient prefetch is always (rightfully) enabled and this patch (nor the module tunable) change that.

@amotin
Copy link
Member

amotin commented Sep 5, 2023

Tri-state switch would be more functional.

Ok, I'll try to implement it.

The prefetcher itself can do only indirects already, as I have mentioned it does it for writes. So it should be trivial.

@shodanshok shodanshok force-pushed the master branch 3 times, most recently from e8ef6c4 to 8175237 Compare September 6, 2023 19:54
Copy link
Member

@amotin amotin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Just needs the style fix and documentation in zfsprops man page.

@shodanshok
Copy link
Contributor Author

Looks good to me. Just needs the style fix and documentation in zfsprops man page.

Done.

@shodanshok
Copy link
Contributor Author

I just corrected a minor style issue.

@ixhamza
Copy link
Member

ixhamza commented Sep 8, 2023

Since there has been a change in zfs_prop_t, the libzfs.abi needs to be updated to avoid the checkabi failure.

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.

Signed-off-by: Gionatan Danti <[email protected]>
@shodanshok
Copy link
Contributor Author

Since there has been a change in zfs_prop_t, the libzfs.abi needs to be updated to avoid the checkabi failure.

Done, thanks.

@shodanshok
Copy link
Contributor Author

Anything I can/should do to get review approval for this PR? Thanks.

@shodanshok
Copy link
Contributor Author

@behlendorf any chances to review this patch? Thanks.

Copy link
Contributor

@behlendorf behlendorf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shodanshok thanks for your patience. If you can rebase this on master and update the PR it should be good to go.

@behlendorf behlendorf added the Status: Accepted Ready to integrate (reviewed, tested) label Oct 20, 2023
@shodanshok
Copy link
Contributor Author

@shodanshok thanks for your patience. If you can rebase this on master and update the PR it should be good to go.

I just synched my branch to master via github "sync" feature. Thank you so much for reviewing this patch.

@behlendorf behlendorf mentioned this pull request Oct 23, 2023
13 tasks
@behlendorf
Copy link
Contributor

The CI failures here are unexpected and look unrelated, but we hit them on multiple builders so clearly something isn't quite right. I see this PR wasn't created on its own branch, I've gone ahead and opened a new PR #15436 to get a fresh test run with the minimal patch cleanly applied to the master branch. Let's see how that goes.

@shodanshok
Copy link
Contributor Author

The CI failures here are unexpected and look unrelated, but we hit them on multiple builders so clearly something isn't quite right.

I noticed the build failures but from their logs I did not spot anything obviously related to this patch.

I see this PR wasn't created on its own branch, I've gone ahead and opened a new PR #15436 to get a fresh test run with the minimal patch cleanly applied to the master branch. Let's see how that goes.

Did I do something non-optimal with the clone/sync from master? Can the build failures be related to that? Are patches better committed in dedicated branches? Sorry if these are basic questions, just trying to better understand for future commits.

And thanks for taking the time to create #15436

@behlendorf
Copy link
Contributor

behlendorf commented Oct 23, 2023

It looks like the CI failures we caused by 797f55e which I just reverted from master with #15438. Assuming that we get a good CI run in #15436 which doesn't include that commit we should be in good shape.

Are patches better committed in dedicated branches?

Yes. When opening a new PR it's generally best to make the change on its own branch. This makes it easy to git rebase -i master your changes on the latest commits in the master branch, and it keeps each change logically separate from anything else you might be working on locally. For future any PRs please go ahead and create them on their own branch.

lundman pushed a commit to openzfsonwindows/openzfs that referenced this pull request Dec 12, 2023
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 remains
a system-wide switch for enable/disable prefetch. However, to avoid
duplication, it would be preferable to deprecate and then remove
the module tunable.

Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Ameer Hamza <[email protected]>
Signed-off-by: Gionatan Danti <[email protected]>
Co-authored-by: Gionatan Danti <[email protected]>
Closes openzfs#15237
Closes openzfs#15436
tonyhutter pushed a commit that referenced this pull request May 2, 2024
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 remains
a system-wide switch for enable/disable prefetch. However, to avoid
duplication, it would be preferable to deprecate and then remove
the module tunable.

Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Ameer Hamza <[email protected]>
Signed-off-by: Gionatan Danti <[email protected]>
Co-authored-by: Gionatan Danti <[email protected]>
Closes #15237 
Closes #15436
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Accepted Ready to integrate (reviewed, tested)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants