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
settings fs: Adding support for csi_save_start/end handlers #42028
Conversation
2d9859a
to
dbe94fa
Compare
@optical-o, thanks for providing the PR. IMO by keeping the file open it is no longer guarantee that when a |
Yes you are correct. The current proposed implementation will break when used with
However i think that is a problem with the implementation of the settings_store api. The redundant writes created by this implementation are in my opinion quite serious because 14s ->200ms when saving around 200 settings options will create enormous amount of erases and writes on the flash. Which will rapidly degrade its life time. The implementation of settings_save_one should be propably surrounded by:
Same as the settings_save is. |
Yes we could use the Another way to utilize these routines would be to set a boolean that avoids opening/closing the file when a The extensive time savings you report would however only apply when a Anyhow, as it is I don't think it is an acceptable proposal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice patch, thanks!
Have a few nits.
Please also follow the project commit message guide.
subsys/settings/src/settings_file.c
Outdated
rc = rc2; | ||
} | ||
} | ||
entry_ctx.stor_ctx = &cf->file; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use tabs (set to 8 spaces wide) for code indentation.
@@ -484,9 +498,6 @@ static int write_handler(void *ctx, off_t off, char const *buf, size_t len) | |||
struct fs_file_t *file = entry_ctx->stor_ctx; | |||
int rc; | |||
|
|||
/* append to file only */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain this removal?
fs_sync() can be used for mitigating this - for littlefs there will be no timing cost as it is strict-write FS. |
If |
@nvlsianpu I will correct the code and prepare it for merging when the final implementation course will be clear. |
Just to clarify the full scope of this PR. I have an issue with settings_save having very poor performance when dealing with larger number of setting entries. As of writing this i see these issues which should be resolved:
I think that proper way of solving this is to utilize the csi_save_start and csi_save_end callback for opening and closing/syncing the file. For this however the issue no. 1 must be resolved due to the settings_save_one not utilizing the csi_save_start/end callbacks. @Laczen I think that other solution would still require modification of the settings_store.c to signal the csi that there will be additional export after this one to prevent the immediate flushing/syncing. In case of |
2c0990d
to
e6a834e
Compare
There is a difference between exporting and calling
This is the real issue and we should focus on this. It is possible (as your PR proposes) to avoid opening and closing the settings (write) file, I am still wondering what is causing the speedup, it is not the opening and closing of the files (as this is done to check for duplicate values anyhow). It could be the fs_seek that can be avoided by keeping the file open (and definitively does not need to be called twice), or the flushing to flash (that will be need to be inserted anyhow for settings_save_one).
What about using the |
subsys/settings/src/settings_file.c
Outdated
int rc; | ||
|
||
fs_file_t_init(&cf->file); | ||
rc = fs_open(&cf->file, cf->cf_name, FS_O_CREATE | FS_O_RDWR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is always appending to the end of file so the FS_O_APPEND
could probably be used here, with no need for fs_seek
invocation bellow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tried to add FS_O_APPEND instead of FS_O_CREATE. The fs_open returned error -2.
I have not tried to know what was the cause. I can try it again an investigate further. It might be that the FS_O_RDWR is not supported when FS_O_APPEND is selected. Any way the RW options should by propably only WR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm tried to add FS_O_APPEND instead of FS_O_CREATE. The fs_open returned error -2. I have not tried to know what was the cause. I can try it again an investigate further.
FS_O_CREATE allows fs_open to create file if such does not exist, you should use both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, you are correct. I will change the implementation to use the APPEND option instead of seek. That will solve the littlefs seek flush issue.
Thank you for your input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change could be done to the existing implementation as well. Is this the cause of the slow performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partially yes. This needs to be solved as well, otherwise the closing of the file(flushing) wont be effective alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So with fs_sync
added after the write you are still getting a dramatic improvement in performance ?
@Laczen If the naming should be changed. It that case your solution appears to be the best one. |
e6a834e
to
41d6003
Compare
I have added @Laczen basic implementation which i will need to test. Currently it is untested. However you can see the implementation using state variable syncing exactly as you proposed. Could you verify that i implemented it as you intended ? |
fd06b18
to
15ed8b2
Compare
Yes, this is how I intended. I am still wondering if the proposed change still gives the drastic improvement from 14s to 200ms? You should anyhow still register the |
I'm swtiching between my branch with older zephyr to this one and missing some lines. sorry about that. |
And i have close the issue by mistake. What a day. |
e8d752a
to
e7c00f5
Compare
I have a problem understanding this, since every write does a |
The issue only occurs when settings_save is called. The is an large amount of settings entries into the file and every single one was flushed either by closing the file or in case of little fs fs_seek(END) the little fs in seek operation flushes the buffer. Now when the syncing flag is off and the file is opened all the time and syncing occurs only at the end of the settings_save so the little fs can utilize its caching capability. Otherwise it would flush around ~4 time for each settings write due to the nature of settings_line write handling (for fs_seek), with the seek fixed(changed to FS_APPEND) it would flush only once per entry. However that is still inefficient when calling settings_save. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect that settings_file_save_end() should call fs_sync() .
Yes, you are correct i made a mistake i had the sync inside start() instead of end. My mistake. |
0174fc5
to
25142c7
Compare
@optical-o, I am still feeling like the change is only getting a speedup from using cache. While this is allowed and would be a good addition from the |
25142c7
to
46b9ed8
Compare
Fixes unnecessary flushes writes of settings file during settings_save call. Replace fs_seek with new fs_open option FS_O_APPEND. Signed-off-by: Tomas Benes <opt@dcw.cz>
46b9ed8
to
d0a690a
Compare
@optical-o, why are you closing this PR? |
Prevents repeated flushing and writing of file during settings_save.
Should increase performance and reduce write cycles when used with littlefs and other fs. #34554
Note i have not tested the compression feature of this fix. I'm using modified version of this module without the compression.