Skip to content

Refactor TDB internal bounds computation #11629

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

Merged
merged 13 commits into from
Mar 30, 2020

Conversation

kyle-cypress
Copy link

@kyle-cypress kyle-cypress commented Oct 4, 2019

Summary of changes

Refactor internal TDB flash bounds computation to reduce code duplication and to provide more viable default values on parts where the program and erase block sizes are close or identical in value.

The default TDBStore internal flash size is determined as the larger of two flash sectors or 14 flash pages (it previously defaulted to two sectors). This increases the usability of the default size computation on devices where the flash sector and page sizes are close or equal to each other.

Impact of changes

Applications which use TDBStore (or another class which wraps it), and do not explicitly specify a value for internal_size in storage_tdb_internal, will consume additional flash space for TDBStore.

Migration actions required

If an application does not already specify internal_size for storage_tdb_internal in its mbed_app.json, and the increased storage is not desired, add an entry to mbed_app.json to explicitly specify the desired size.
If an application already specifies internal_size for storage_tdb_internal in its mbed_app.json, no changes are required.

Documentation

N/A


Pull request type (required)

[x] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results (required)

[] No Tests required for this change (E.g docs only update)
[x] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers

@ciarmcom ciarmcom requested review from a team October 4, 2019 03:00
@ciarmcom
Copy link
Member

ciarmcom commented Oct 4, 2019

@kyle-cypress, thank you for your changes.
@ARMmbed/mbed-os-storage @ARMmbed/mbed-os-maintainers please review.

@JanneKiiskila
Copy link
Contributor

Attn @SeppoTakalo @ARMmbed/team-st-mcd

@kyle-cypress kyle-cypress force-pushed the pr/tdb-bounds-refactor branch from 2814f11 to d6a1ac6 Compare October 4, 2019 14:41
Comment on lines 1493 to 1471
MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
if (curr_addr < first_wrtbl_sector_addr) {
ret = MBED_ERROR_MEDIA_FULL;
} else {
*start_address = curr_addr;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

@SeppoTakalo should we maybe use MBED_ERROR here? To replace all the highlighted lines.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would be too big API change.. maybe for the OS version 6.

}

//Check that internal flash has 2 or more sectors
if (_calculate_blocksize_match_tdbstore(kvstore_config.internal_bd) != MBED_SUCCESS) {
//Check if TDBStore has at least 2 sector.
Copy link
Contributor

Choose a reason for hiding this comment

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

*s or 10 pages.

Copy link
Contributor

Choose a reason for hiding this comment

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

Why would 10 pages work instead of a full sector? I think TDBSTore uses the flash sectors to do the garbage collection, in sort of A vs. B, one of them being active and the other one as the spare?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, that matches my understanding of TDBStore's garbage collection - it divides the available flash area in half and alternates between the two to do copying GC.
The problem is that the default approach breaks down when the sector size and page sizes are the same (or close), because many of the KVStore operations consume an entire page. Based on our analysis of the KVStore greentea tests as a proxy for typical usage, the minimum page count appeared to be around 10 i.e. 5 pages in active use, 5 in reserve for GC (or 2 sectors if that is larger, so that GC continues to work). If there's a different number of pages that more directly corresponds to something intrinsic in the driver I'd be happy to go with that instead.

Copy link
Author

@kyle-cypress kyle-cypress Oct 29, 2019

Choose a reason for hiding this comment

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

@VeijoPesonen, with regard to:

*s or 10 pages.

Wouldn't expanding this check produce a backwards compatibility concern? Or does this qualify as a situation where it would probably have always failed, just in a less explicit manner, and therefore it is okay to add a new error condition?

Copy link
Author

Choose a reason for hiding this comment

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

@VeijoPesonen, can you please confirm that the expanded check is not a backwards compatibility concern?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi, was browsing some PRs randomly, sorry for jumping in.

The number of pages TDBStore needs depends on the number of KV pairs+1. So for 4 KV pairs it needs 5 pages. (Actually it may need 2 pages per KV pair, not sure).

Unfortunately I think this means you can't make this check unless you know the number of KV pairs beforehand.

Copy link
Author

Choose a reason for hiding this comment

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

I agree that you can't compute a minimum that is guaranteed to be enough unless you know how much is intended to be stored. However, there is a bare minimum size (e.g. space for internal bookkeeping, a second sector for garbage collection) below which TDBStore cannot function. That is what this check is intended to achieve. Are you saying that the bare minimum page count calculation should be different?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, my understanding was that the theoretical minimum would be 4 pages total (2 for the active master record, 2 for the old master record, where pages = program size'd units). But my understand could be out of date.

Out of curiousity do you know where the other 2x3 pages come from?

Copy link
Author

Choose a reason for hiding this comment

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

I not able to determine precisely where that came from.
However, after further consideration I've removed the hard-fail on too few pages given that the exact minimum is application specific. Full reasoning is in the commit message for a3a4eef59939741999101f1eb5b4367f422f9e6e

@0xc0170 0xc0170 requested a review from SeppoTakalo October 17, 2019 13:23
@0xc0170 0xc0170 requested a review from VeijoPesonen October 18, 2019 13:32
@0xc0170 0xc0170 added the release-version: 6.0.0-alpha-1 First pre-release version of 6.0.0 label Oct 18, 2019
@0xc0170
Copy link
Contributor

0xc0170 commented Oct 21, 2019

@ARMmbed/mbed-os-storage Please help reviewing this PR

@VeijoPesonen
Copy link
Contributor

VeijoPesonen commented Oct 22, 2019

@0xc0170 work in progress, let's give @kyle-cypress time to address the remaining issues. He seems to have a higher priority PR to finish first.

@0xc0170
Copy link
Contributor

0xc0170 commented Nov 4, 2019

@kyle-cypress This PR was updated, what is the current status?

@kyle-cypress
Copy link
Author

There are two items left that I know of:

  1. Need a response to my question in Refactor TDB internal bounds computation #11629 (comment) about whether it is okay to add the additional check as suggested
  2. There is an open question to @SeppoTakalo in Refactor TDB internal bounds computation #11629 (comment) ; I'm not sure if that gates this PR or not.

@@ -2,11 +2,11 @@
"name": "storage_filesystem",
"config": {
"rbp_internal_size": {
"help": "Default is the size of the 2 last sectors of internal flash",
"help": "Default is the larger of the last 2 sectors or last 10 pages of flash.",
Copy link
Contributor

Choose a reason for hiding this comment

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

You later specify TDBStore ::STORE_PAGES to 14, so why this is 10?

Copy link
Author

Choose a reason for hiding this comment

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

Because STORE_PAGES was increased and the comment update was missed. I will fix.

tr_warning("KV Config: There are less than two sectors - TDBStore will not work.");
return -1;
}

if (number_of_page < TDBStore::STORE_PAGES) {
tr_warning("KV Config: There are less than fourteen pages - TDBStore will not work.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be tr_error(), and preferably change the previous as well.

Also not sure whether TDBStore::STORE_PAGES can change in the future, so perhaps use less than %d pages.

#else
return NULL;
#endif
}

BlockDevice *_get_blockdevice_SPIF(bd_addr_t start_address, bd_size_t size)
BlockDevice *_get_blockdevice_SPIF(bd_addr_t &start_address, bd_size_t &size)
Copy link
Contributor

Choose a reason for hiding this comment

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

If we change the API, should we use pointers instead of references?
Makes it more obvious for caller that the values can change. I don't really like references for trivial types.

Copy link
Author

Choose a reason for hiding this comment

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

I looked through the current changeset and nothing uses the returned value anymore. I will revert the argument type change.

Comment on lines 1493 to 1471
MBED_ASSERT(curr_addr >= first_wrtbl_sector_addr);
if (curr_addr < first_wrtbl_sector_addr) {
ret = MBED_ERROR_MEDIA_FULL;
} else {
*start_address = curr_addr;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be too big API change.. maybe for the OS version 6.

@0xc0170
Copy link
Contributor

0xc0170 commented Nov 8, 2019

@kyle-cypress Please review the latest comments from @SeppoTakalo

@kyle-cypress kyle-cypress force-pushed the pr/tdb-bounds-refactor branch from 2899562 to c52d452 Compare November 9, 2019 02:21
@kyle-cypress
Copy link
Author

I've pushed up changes that I believe address all of the remaining change requests. I still need confirmation that the change suggested in #11629 (comment) (it is included in the current changeset) is not a backwards compatibility problem.
I also rebased on master to pick up the fix in #11810.

@SeppoTakalo
Copy link
Contributor

Looks OK.

This has already been labeled as 6.0, so I would not worry about being backward compatible.
Using storage, without explicitly setting its location should already be documented as a "experimental development feature" and nobody goes into production with setup like that.

Copy link
Contributor

@VeijoPesonen VeijoPesonen 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

Kyle Kearney added 8 commits March 24, 2020 12:27
Increase minimum page count from 10 to 14 based on further experiments
with features-storage-tests-kvstore-static_tests.
No callers make use of the modified argument values, so change
them to a more straightforward pass by value.
Replace custom caluation that always assumed two sectors with the standard
calculation exposed on TDBStore.
STORE_SECTORS is a hard requirement. If there are fewer than 2 pages
then the kvstore will not work, because the garbage collection process
relies on having at least two sectors to work with.
STORE_PAGES is a heuristic. It is a reasonable default to use if the
application does not specify the amount of flash to use for TDBStore.
But if an application knows that a smaller number of pages will suffice
for its specific needs, then that is valid and should be permitted.
The unittests compile DirectAccessDeviceKey.cpp which depends on
kv_config.h, which lives in features/storage/kvstore/conf
@kyle-cypress kyle-cypress force-pushed the pr/tdb-bounds-refactor branch from 6d730b4 to 85d2e8f Compare March 24, 2020 19:38
@kyle-cypress
Copy link
Author

The unittest failure is because kv_config.h is included from DirectAccessDeviceKey.cpp, but its containing folder is not in the include path for the unittest build. I pushed up 85d2e8f (rebasing again in the process) which adds an entry to UNITTESTS/CMakeLists.txt. This fixed the build when I tested it out locally, but I'm not sure if that is the right place to make this change.

@kyle-cypress
Copy link
Author

Also, FYI, the "Build Artifacts" link posted above by mbed-ci still doesn't contain any logs related to failing tests.

@0xc0170
Copy link
Contributor

0xc0170 commented Mar 25, 2020

CI restarted

@mbed-ci
Copy link

mbed-ci commented Mar 25, 2020

Test run: FAILED

Summary: 1 of 6 test jobs failed
Build number : 7
Build artifacts

Failed test jobs:

  • jenkins-ci/mbed-os-ci_greentea-test

@mergify mergify bot added needs: work and removed needs: CI labels Mar 25, 2020
@kyle-cypress
Copy link
Author

The failures for NUCLEO_F429ZI are in network and netsocket, which this PR doesn't touch. Is this a CI issue?
As far as I can tell, that is the only failure, but please let me know if there are others that I'm not seeing in the build artifacts.

@0xc0170
Copy link
Contributor

0xc0170 commented Mar 26, 2020

CI restarted

@kyle-cypress
Copy link
Author

Updated PR summary to match the latest template from https://os.mbed.com/docs/mbed-os/v5.15/contributing/workflow.html#pull-request-template

@adbridge
Copy link
Contributor

CI restarted

@adbridge
Copy link
Contributor

hi @kyle-cypress you're still slightly out, see #12472 for current template. May be our docs need a tweak too

@kyle-cypress
Copy link
Author

Yes, I think the template in the workflow doc is slightly off. Should be up to date now.

@mbed-ci
Copy link

mbed-ci commented Mar 27, 2020

Test run: SUCCESS

Summary: 6 of 6 test jobs passed
Build number : 8
Build artifacts

@0xc0170 0xc0170 merged commit 4c6e59d into ARMmbed:master Mar 30, 2020
@mergify mergify bot removed the ready for merge label Mar 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.