-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Regression in 3ec34e55: ARC-related tunable module parameter values are no longer applied at runtime #8405
Comments
The behaviour of zfs_arc_max is described correctly and behaves as you witnessed according to the doc at |
If the goal is to cause the ARC to shrink, then there is a process that can be made using
|
Perhaps the particular example I gave (of decreasing the value of The problem I'm describing in this issue isn't "help, my ARC won't shrink when I reduce |
Yeah so, the problem with any of this would be that writing literally any value into Sure, the module parameter value itself changes. But the actual value of the actual variable Read the issue report again... |
I'm trying to get to a procedural documented expectation of behaviour to help with your bug report. It would help to have use cases that make sense for dynamic tuning and I think you've provided one. If you'd rather not have help, then feel free to submit a PR. |
Please try to understand that my bug report really has nothing to do with any particular one dynamic tuning use case not working. My concern was not "yikes, why is the ARC usage not decreasing like I thought it would?"; but rather, "yikes, why is it that when I change (for example) the ARC limit to some value, the ARC limit doesn't actually change to that value, or at all for that matter?".
To be really pedantic... the expected behavior is that if I modify Here is a comprehensive list of things that should happen, which don't happen:
The only way any of those module parameters are actually read in and applied to the ARC at all is via the function Hence, all of the module parameters that I listed in the issue report can have their apparent values changed as much as you want via sysfs (at post-module-load-time), but it will have zero effect on the ARC because My own naive attempt at a fix would be to insert a call to But I'm not familiar enough with the specifics here to know for sure whether that's actually the equivalent place to old call site; nor whether this placement has 100% correct behavior WRT locking and so forth (which is complicated stuff that's easy to screw up). --- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -5075,37 +5075,39 @@ arc_kmem_reap_soon(void)
/* ARGSUSED */
static boolean_t
arc_adjust_cb_check(void *arg, zthr_t *zthr)
{
+ arc_tuning_update();
+
/*
* This is necessary in order to keep the kstat information
* up to date for tools that display kstat data such as the
* mdb ::arc dcmd and the Linux crash utility. These tools
* typically do not call kstat's update function, but simply
* dump out stats from the most recent update. Without
* this call, these commands may show stale stats for the
* anon, mru, mru_ghost, mfu, and mfu_ghost lists. Even
* with this change, the data might be up to 1 second
* out of date(the arc_adjust_zthr has a maximum sleep
* time of 1 second); but that should suffice. The
* arc_state_t structures can be queried directly if more
* accurate information is needed.
*/
if (arc_ksp != NULL)
arc_ksp->ks_update(arc_ksp, KSTAT_READ);
/*
* We have to rely on arc_get_data_impl() to tell us when to adjust,
* rather than checking if we are overflowing here, so that we are
* sure to not leave arc_get_data_impl() waiting on
* arc_adjust_waiters_cv. If we have become "not overflowing" since
* arc_get_data_impl() checked, we need to wake it up. We could
* broadcast the CV here, but arc_get_data_impl() may have not yet
* gone to sleep. We would need to use a mutex to ensure that this
* function doesn't broadcast until arc_get_data_impl() has gone to
* sleep (e.g. the arc_adjust_lock). However, the lock ordering of
* such a lock would necessarily be incorrect with respect to the
* zthr_lock, which is held before this function is called, and is
* held by arc_get_data_impl() when it calls zthr_wakeup().
*/
return (arc_adjust_needed);
} |
I'm seeing the same thing: After setting the following settings, arc_summary still shows the prior
I also tried to set the settings at boot time via
This too failed to change the The only remaining option was to set zfs_arc_max and zfs_arc_min through kernel settings via
P.S.: Thanks kpande for the workaround! |
@jgottula thanks for catching this and isolating the exact commit where it was introduced. You're proposed fix above is the right one, would you mind opening a PR with the change. I'd only suggest that you add a comment above the call to /*
* This is necessary in order to periodically propagate changes
* made to the zfs_arc* module options to the internal counterparts.
*/
arc_tuning_update();
This was actually merged on Dec 26, 2018. This is a change which was originally authored a while ago but was only finalized and committed within the last few months.
|
Done! #8463
Ah, good catch. Git date confusion strikes again... And that makes more sense anyway. I've been using the master branch for quite a while, and it didn't quite seem like the breakage had been affecting me for two entire years... |
I am running zfs 0.8.0-208_g142f84dd1 and the issue is still present:
I confirmed that the sources I used to compile zfs comprise the patch approved on 12 March 2019. |
System information
Quick summary before the long version
Commit 3ec34e5 (Mar 15 2017) reworked
arc_reclaim_thread
, and in doing so, seems to have unintentionally removed a call toarc_tuning_update
that was necessary for several ARC-tuning-related zfs module parameters to be able to have their changes applied properly at runtime.This issue has likely affected anyone using the master branch since
Mar 15 2017Dec 26 2018; as well as release 0.8.0-rc3 from Jan 14 2019. (I checked the other release tags, and 0.8.0-rc3 appears to be the first one to have included thearc_reclaim_thread
rework from 3ec34e5.)The problem I encountered
(Edit: Please note that this issue report is not meant to concern this particular case of ARC behavior not working as expected or whatever; the concern is with the fact that a bunch of module parameters do literally nothing when their value is changed, for completely explainable reasons elaborated on elsewhere in this post.)
Today, I noticed that my machine was swapping due to the ARC taking up all 8 GiB of memory I had allotted to it while I was running some high-memory-usage compression tasks. So I decided to decrease
zfs_arc_max
down from 8 GiB to 6 GiB.I went to a terminal and did
echo $((6*(1<<30))) >/sys/module/zfs/parameters/zfs_arc_max
as root. Nothing actually happened. I could read the value back, i.e.cat /sys/module/zfs/parameters/zfs_arc_max
now showed6442450944
instead of8589934592
.But watching
/proc/spl/kstat/zfs/arcstats
indicated no actual change to anything.And
arc_summary --section arc
likewise indicated no actual change to anything.My investigation into the cause of the problem
I could swear that it used to be possible to change these things at runtime. So I rummaged through the zfs source code to see how the module parameters are applied.
The values of many of the ARC tunable kernel module parameters are not used directly, but are instead used in an indirect manner:
arc_tuning_update
takes the raw mod param values and assigns them to the variables that the ARC actually looks at directly, clamping the raw values as needed.Here are all of the module parameters that work in this way:
So, a change to
/sys/module/zfs/parameters/zfs_arc_max
will change the value ofzfs_arc_max
inmodule/zfs/arc.c
. Butzfs_arc_max
isn't used by anything;arc_c_max
is what actually matters. Andzfs_arc_max
's value is only actually assigned toarc_c_max
inarc_tuning_update
.Now, the documentation (function comment) for
arc_tuning_update
purports:But I could only locate one call to
arc_tuning_update
in the entire repository, which was inarc_init
:The "called during module initialization and periodically thereafter" documentation didn't match up to the reality. And it made more sense to me that this was a case of the code accidentally being broken at some time, than a case of the documentation being wrong (given that I remembered it working in the past).
So I looked for any commits in the history that had in any way referenced the word
arc_tuning_update
, viagit log -Garc_tuning_update
. This only turned up two commits:arc_tuning_update
function in the first place.arc_reclaim_thread
; and in checking the commit diff, a call toarc_tuning_update
was removed fromarc_reclaim_thread
, but no new call to the function was added in replacement.Conclusions and what to do about this
So it appears that the
arc_reclaim_thread
rework accidentally removed the not-at-init-time calls toarc_tuning_update
.Probably one of the two replacement thread functions (
arc_adjust_cb
orarc_reap_cb
) should be making that call. I don't know which should be calling it; or if there's some different way it ought to be done now. But hopefully just raising awareness of the problem is sufficient for you guys to know how to fix it up properly.How to reproduce the problem
/sys/module/zfs/parameters/$PARAM
./sys/module/zfs/parameters/$PARAM
back./proc/spl/kstat/zfs/arcstats
, orarc_summary --section arc
, or whatever), that the new value doesn't actually affect the functioning of the ARC itself.Other issues that could possibly have been caused by this
#6540 #6852
Both of these are from the affected date range. The latter issue seems much more plausibly affected by this than the former does, as it mentioned using the git master code, whereas the other one mentioned using zfs version 0.6.5.6 (albeit with Ubuntu patches, so who the hell knows).
The text was updated successfully, but these errors were encountered: