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

sys/log: Add optional support for sector bookmarks to optimize reading logs #3365

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

vrahane
Copy link
Contributor

@vrahane vrahane commented Jan 30, 2025

  • This adds sector bookmarks for reading optimization, earlier only absolute bookmarks were supported
  • Retain older absolute bookmarks behavior. Added a syscfg for specifying number of absolute bookmarks.
  • Added a syscfg to optionally enable sector bookmarks.
  • CLI: Add '-i' option in log_shell for specifying index where log read should start
  • CLI: Add '-b' option in log_shell for reading bookmarks

For mixed bookmarks:

  • Sector bookmarks are from 0 -> sector_cnt of the flash area in the array.
  • Non-sector/Absolute bookmarks are from sector_cnt -> LOG_FCB_NUM_ABS_BMARKS (2 by default)

Several tests were performed:

  • Reboot test, bookmarks should get reset
  • New log entries populate the bookmarks, specially for sector boundaries
  • Test absolute bookmarks behavior, both with mixed bookmarks (sector + absolute) as well as just absolute bookmarks with sector bookmarks disabled

@vrahane vrahane changed the title sys/log: Add bookmarks per sector to optimize reading logs sys/log: Add optional support for sector bookmarks to optimize reading logs Jan 30, 2025
@vrahane vrahane force-pushed the vipul/bmarks branch 3 times, most recently from bf7d968 to efdadf6 Compare January 30, 2025 22:45
@github-actions github-actions bot added size/l and removed size/m labels Jan 30, 2025
@vrahane vrahane force-pushed the vipul/bmarks branch 7 times, most recently from deafc14 to 0e3bcee Compare February 14, 2025 02:44
- Add sector bookmarks for reading optimization
- Retain older absolute bookmarks behavior
- CLI: Add '-t' option in log_shell for measuring read time (cherry-picking Jerzy's
commit)
- CLI: Add '-b' option in log_shell for reading bookmarks
Copy link
Contributor

@kasjer kasjer left a comment

Choose a reason for hiding this comment

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

  • Code will not build for FCB2
  • It's not clear how to choose size for bookmarks array
  • If suggested size is around number of sector of the FCB flash area, RAM usage can be an issue. For 384 sectors' FCB RAM usage is over 12KB
  • There are places that use code and RAM space even if no bookmarks/sector-bookmarks are enabled

@vrahane vrahane force-pushed the vipul/bmarks branch 4 times, most recently from 3bcb976 to 8f26895 Compare February 15, 2025 02:57
@vrahane vrahane requested a review from kasjer February 15, 2025 10:34
@vrahane vrahane force-pushed the vipul/bmarks branch 3 times, most recently from 39d40d1 to 9611300 Compare February 17, 2025 20:09
@kasjer
Copy link
Contributor

kasjer commented Feb 18, 2025

@kasjer Once I have addressed them, I resolve them. You can just click on them one by one and check. They don't go anywhere. I dont mark them as unresolved unless I have addressed them. Also, please don't re-review yet. I am still seeing non-sector bookmarks having an issue after I addressed all the review comments. I need to debug that.

When you addressed them it clearly does not mean they are resolved them

@vrahane
Copy link
Contributor Author

vrahane commented Feb 18, 2025

Ok, whichever you feel is not done, please un-resolve it.

@vrahane
Copy link
Contributor Author

vrahane commented Feb 18, 2025

@kasjer I have tried to address all comments. Please let me know what you think ?

Copy link
Contributor

@kasjer kasjer left a comment

Choose a reason for hiding this comment

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

Tested with FCB2 and while it compiles it does not seems that functionality works.
I did not try to look what is wrong but dump from bookmark table is strange
compat> log -b

016463 0: index: 99 entry: 24003088 fr: 2400306c fe_sector: 0 fe_data_off: e62
016464 1: index: 98 entry: 2400309c fr: 2400306c fe_sector: 0 fe_data_off: df8
016467 2: index: 97 entry: 240030b0 fr: 2400306c fe_sector: 0 fe_data_off: d86
016474 3: index: 96 entry: 240030c4 fr: 2400306c fe_sector: 0 fe_data_off: d40
016481 4: index: 95 entry: 240030d8 fr: 2400306c fe_sector: 0 fe_data_off: cdc
016488 5: index: 94 entry: 240030ec fr: 2400306c fe_sector: 0 fe_data_off: c9a
016495 6: index: 93 entry: 24003100 fr: 2400306c fe_sector: 0 fe_data_off: c54
016502 7: index: 92 entry: 24003114 fr: 2400306c fe_sector: 0 fe_data_off: c17
016509 8: index: 91 entry: 24003128 fr: 2400306c fe_sector: 0 fe_data_off: baf
016516 9: index: 90 entry: 2400313c fr: 2400306c fe_sector: 0 fe_data_off: b5f

It does not look like bookmarks refer to separate sector as is the case for FCB

@@ -231,7 +231,7 @@ ltfbu_init(const struct ltfbu_cfg *cfg)
TEST_ASSERT_FATAL(rc == 0);

if (cfg->bmark_count > 0) {
log_fcb_init_bmarks(&ltfbu_fcb_log, ltfbu_bmarks, cfg->bmark_count);
log_fcb_init_bmarks(&ltfbu_fcb_log, ltfbu_bmarks, cfg->bmark_count, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the only place in mynewt repository where log_fcb_init_bmarks() is called. When I try to put similar code (except last argument is true) in actual code system crashes.
Is there a restriction on when this function should be called?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, there is no restrictions as such, I called it on the fcb from the slinky app and that seemed to work. Where did you call it from ?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is test function called from main after

int
test_log_init(void)
{
    const struct flash_area *fa;
    struct fcb *fcbp;
    int sector_count;
    int rc;

    if (flash_area_open(FLASH_AREA_TEST_LOG, &fa)) {
        return SYS_EUNKNOWN;
    }

    flash_area_to_sectors(FLASH_AREA_TEST_LOG, &sector_count, NULL);
    test_log_sectors = calloc(sector_count, sizeof(*test_log_sectors));
    flash_area_to_sectors(FLASH_AREA_TEST_LOG, &sector_count, test_log_sectors);
    test_log_fcb.fl_entries = 0;
    fcbp = &test_log_fcb.fl_fcb;

    fcbp->f_magic = 0x7EADBADF;
    fcbp->f_version = g_log_info.li_version;
    fcbp->f_sector_cnt = sector_count - 1;
    fcbp->f_scratch_cnt = 1;
    fcbp->f_sectors = test_log_sectors;

    rc = fcb_init(fcbp);
    if (rc) {
        flash_area_erase(fa, 0, fa->fa_size);
        rc = fcb_init(fcbp);
        if (rc) {
            return rc;
        }
    }

#if MYNEWT_VAL_LOG_FCB_SECTOR_BOOKMARKS
    int bookmark_count = fcbp->f_sector_cnt + MYNEWT_VAL_LOG_FCB_NUM_ABS_BOOKMARKS;
    test_log_bookmarks = malloc(bookmark_count * sizeof(*test_log_bookmarks));

    log_fcb_init_bmarks(&test_log_fcb, test_log_bookmarks, bookmark_count, true);
#endif

    rc = log_register("test_log", &test_log, &log_fcb_handler,
                      &test_log_fcb, LOG_SYSLEVEL);

    return rc;
}

Order of calls based on the only example found in unit tests except unit tests call to log_fcb_init_bmarks() has false as last argument:

  • fcb_init()
  • log_fcb_init_bmarks() <- crashes inside
  • log_register()

Comment on lines 246 to 248
if (bset->lfs_size && bset->lfs_size > pos && pos != (bset->lfs_cap - 1)) {
memmove(&bset->lfs_bmarks[pos + 1], &bset->lfs_bmarks[pos],
sizeof(bset->lfs_bmarks[0]) * (bset->lfs_size - pos));
Copy link
Contributor

Choose a reason for hiding this comment

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

This code keeps sector bookmarks sorted by index.
It does not look like any other place in the code takes advantage of this order. When bookmarks are search for match this order is not utilized.
Maybe there is not need to move chunk of memory every time when sector bookmark is inserted which seems to be the case since sector are scanned from the oldest one. So every sector bookmark result in memmove with increasing size.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was done because earlier absolute bookmarks could actually be in between the other bookmarks based on the index. Even now, insertion happens as pos 0 but, we could optimize it so that there is no memmove happening. Let me try it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I did optimize the code quite a bit. Please take a look. As per the review comment I have removed memmove.

* If sector bookmarks are enabled, buffer should be big enough
* to accomodate bookmarks for the entire flash area that is allocated
* for the FCB log, i,e; sizeof(struct log_fcb_bmark) *
* my_log.fl_fcb.f_sector_cnt + MYNEWT_VAL(LOG_FCB_NUM_ABS_BOOKMARKS)
Copy link
Contributor

Choose a reason for hiding this comment

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

It can't stay like this. The function should return an error if buffer is too small and not just crash later on. But actually it would be better if it can work with smaller buffers as well and e.g. place bookmark every n-th sector or just skip bookmarks that don't fit in the buffer.

Copy link
Contributor Author

@vrahane vrahane Feb 22, 2025

Choose a reason for hiding this comment

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

That is possible but it complicates the code further. Just failing is a better approach. The user should know what they are doing. What if they have a bigger buffer ? Then we will have to handle that too. I would like to keep it a bit restricted in its usage.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's not complicated. It's just a simple if statement added to log_fcb_init_sector_bmarks so log_fcb_add_bmark is not called for every sector.

You can simply calculate max number of bookmarks from the buffer size and then either add at most that number of bookmarks or, even better, divide number of sectors by that number and insert bookmark every n-th sector only so it doesn't overflow buffer. I don't ask you to handle any special cases, e.g. if the buffer is too big then it will simply have some free space left.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, let me give it a shot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@andrzej-kaczmarek Ok, I have added support for this. Please take a look. I am going to exercise it little bit more to make sure there are no edge cases I have forgotten.

@vrahane vrahane force-pushed the vipul/bmarks branch 2 times, most recently from 5471eaa to b2fb7fc Compare February 26, 2025 00:39
@vrahane
Copy link
Contributor Author

vrahane commented Feb 26, 2025

@kasjer and @andrzej-kaczmarek build failures are unrelated.

@kasjer
Copy link
Contributor

kasjer commented Feb 26, 2025

This time I did not look at the code just tested it on the entirely full fcb log on 1MB spi flash with 6 absolute bookmarks.
It seems that after 6 walks sector bookmark are no longer used
here are some output from log console

compat> log -b test_log
0: index:0 entry: 20007d28 fa: 0 fe_elem_off: 0
017947 1: index:68837 entry: 20007d44 fa: 2000713c fe_elem_off: 2c
...
018263 250: index:15108 entry: 20009880 fa: 20007184 fe_elem_off: a5
018265 251: index:13154 entry: 2000989c fa: 20007178 fe_elem_off: 2b
018266 252: index:11764 entry: 200098b8 fa: 2000716c fe_elem_off: 2b
018267 253: index:10262 entry: 200098d4 fa: 20007160 fe_elem_off: 2a
018269 254: index:8819 entry: 200098f0 fa: 20007154 fe_elem_off: 8
018270 255: index:0 entry: 2000990c fa: 0 fe_elem_off: 0
018271 256: index:0 entry: 20009928 fa: 0 fe_elem_off: 0
018272 257: index:0 entry: 20009944 fa: 0 fe_elem_off: 0
018273 258: index:0 entry: 20009960 fa: 0 fe_elem_off: 0
018275 259: index:0 entry: 2000997c fa: 0 fe_elem_off: 0
018275 260: index:0 entry: 20009998 fa: 0 fe_elem_off: 0

Last 6 elements are for absolute bookmarks I guess
Now command to measure time of walking 2 entries from index (visible in sector bookmarks)

compat> log -i 10262 -n 2 -t test_log
253519 Log test_log 2 entries walked in 83 ms
compat> log -b test_log
362773 0: index:0 entry: 20007d28 fa: 0 fe_elem_off: 0
362774 1: index:68837 entry: 20007d44 fa: 2000713c fe_elem_off: 2c
...
363093 252: index:11764 entry: 200098b8 fa: 2000716c fe_elem_off: 2b
363094 253: index:10262 entry: 200098d4 fa: 20007160 fe_elem_off: 2a
363096 254: index:8819 entry: 200098f0 fa: 20007154 fe_elem_off: 8
363097 255: index:10262 entry: 2000990c fa: 20007160 fe_elem_off: 2a  <------------ Duplicate
363098 256: index:0 entry: 20009928 fa: 0 fe_elem_off: 0
363099 257: index:0 entry: 20009944 fa: 0 fe_elem_off: 0
363100 258: index:0 entry: 20009960 fa: 0 fe_elem_off: 0
363102 259: index:0 entry: 2000997c fa: 0 fe_elem_off: 0
363103 260: index:0 entry: 20009998 fa: 0 fe_elem_off: 0

Now duplicate entry is present in absolute bookmark space (previously it was not the case)
This time measure walk time from index 50010 which also is present in sector bookmarks

compat> log -i 50010 -n 2 -t test_log
571519 Log test_log 2 entries walked in 32 ms
compat> log -b test_log
685500 0: index:0 entry: 20007d28 fa: 0 fe_elem_off: 0
685501 1: index:68837 entry: 20007d44 fa: 2000713c fe_elem_off: 2c
...
685611 88: index:50170 entry: 200086c8 fa: 2000791c fe_elem_off: 2b
685612 89: index:50010 entry: 200086e4 fa: 20007910 fe_elem_off: 2a
685614 90: index:49888 entry: 20008700 fa: 20007904 fe_elem_off: 2a
...
685821 253: index:10262 entry: 200098d4 fa: 20007160 fe_elem_off: 2a
685823 254: index:8819 entry: 200098f0 fa: 20007154 fe_elem_off: 8
685824 255: index:10262 entry: 2000990c fa: 20007160 fe_elem_off: 2a <--- Both were present in sector bookmarks
685825 256: index:50010 entry: 20009928 fa: 20007910 fe_elem_off: 2a <---
685827 257: index:0 entry: 20009944 fa: 0 fe_elem_off: 0
685828 258: index:0 entry: 20009960 fa: 0 fe_elem_off: 0
685829 259: index:0 entry: 2000997c fa: 0 fe_elem_off: 0
685830 260: index:0 entry: 20009998 fa: 0 fe_elem_off: 0

Walk is fast as expected
Next few walks without hitting sector bookmark

compat> log -i 30000 -n 2 -t test_log
926885 Log test_log 2 entries walked in 528 ms
compat> log -i 20000 -n 2 -t test_log
964547 Log test_log 2 entries walked in 252 ms
compat> log -i 10000 -n 2 -t test_log
969795 Log test_log 2 entries walked in 114 ms
compat> log -i 15000 -n 2 -t test_log
979476 Log test_log 2 entries walked in 117 ms
compat> log -i 11000 -n 2 -t test_log
986830 Log test_log 2 entries walked in 21 ms
compat> log -i 12000 -n 2 -t test_log
994202 Log test_log 2 entries walked in 26 ms
compat> log -i 13000 -n 2 -t test_log
997642 Log test_log 2 entries walked in 29 ms
compat> log -b test_log
1102179 0: index:0 entry: 20007d28 fa: 0 fe_elem_off: 0
1102180 1: index:68837 entry: 20007d44 fa: 2000713c fe_elem_off: 2c
...
1102506 254: index:8819 entry: 200098f0 fa: 20007154 fe_elem_off: 8
1102507 255: index:11000 entry: 2000990c fa: 20007160 fe_elem_off: 8cc
1102508 256: index:12000 entry: 20009928 fa: 2000716c fe_elem_off: 350
1102510 257: index:13000 entry: 20009944 fa: 2000716c fe_elem_off: ea9
1102511 258: index:20000 entry: 20009960 fa: 200071a8 fe_elem_off: 882
1102513 259: index:10000 entry: 2000997c fa: 20007154 fe_elem_off: cc8
1102514 260: index:15000 entry: 20009998 fa: 20007184 fe_elem_off: a5

Times seems to vary depending on index, grater index -> slower walk
Now all absolute bookmarks are there plus 255 sector ones
Measure time for walking 2 entries starting from index 50000

compat> stat spiflash
1228621 read_count: 19885
1228621 write_count: 4
1228622 erase_count: 0
1228622 error_count: 0
1228623 read_bytes: 215750
1228623 written_bytes: 157
compat> log -i 50000 -n 2 -t test_log
1256664 Log test_log 2 entries walked in 5869 ms
compat> stat spiflash
1259963 read_count: 96353
1259963 write_count: 4
1259964 erase_count: 0
1259964 error_count: 0
1259965 read_bytes: 1159963
1259965 written_bytes: 157

And here is measurements when sector bookmarks are off, this is single session

compat> log -i 50000 -n 2 -t test_log
Log test_log 2 entries walked in 67 ms
compat> log -i 10000 -n 2 -t test_log
030365 Log test_log 2 entries walked in 113 ms
compat> log -i 20000 -n 2 -t test_log
033948 Log test_log 2 entries walked in 101 ms
compat> log -i 30000 -n 2 -t test_log
037504 Log test_log 2 entries walked in 101 ms
compat> log -i 40000 -n 2 -t test_log
041646 Log test_log 2 entries walked in 80 ms
compat> log -i 10000 -n 2 -t test_log
046245 Log test_log 2 entries walked in 114 ms
compat> log -i 50000 -n 2 -t test_log
054318 Log test_log 2 entries walked in 66 ms
compat> log -i 10000 -n 2 -t test_log
061018 Log test_log 2 entries walked in 114 ms
compat> log -i 11000 -n 2 -t test_log
065112 Log test_log 2 entries walked in 104 ms
compat> log -i 13000 -n 2 -t test_log
067719 Log test_log 2 entries walked in 120 ms
compat> log -i 14000 -n 2 -t test_log
070770 Log test_log 2 entries walked in 110 ms
compat> log -i 15000 -n 2 -t test_log
073969 Log test_log 2 entries walked in 83 ms
compat> log -i 16000 -n 2 -t test_log
078615 Log test_log 2 entries walked in 107 ms
compat> log -i 50000 -n 2 -t test_log
083399 Log test_log 2 entries walked in 66 ms

Without sector bookmarks (absolute bookmarks are enabled) timing seems reasonable.

@vrahane
Copy link
Contributor Author

vrahane commented Feb 27, 2025

@kasjer I do not see the issues you mentioned above with my setup with default number of absolute bookmarks and using the sector count for sector bookmarks. Attaching the coolterm output.
CoolTerm Capture 2025-02-27 13-28-04.txt

This is my initialization code:

264     log_test_bmarks = malloc((log_test_fcb.fl_fcb.f_sector_cnt +
265                                      MYNEWT_VAL(LOG_FCB_NUM_ABS_BOOKMARKS)) *
266                                     sizeof(*log_test_bmarks));
267     memset(log_test_bmarks, 0, (log_test_fcb.fl_fcb.f_sector_cnt +
268                                        MYNEWT_VAL(LOG_FCB_NUM_ABS_BOOKMARKS)) *
269                                        sizeof(*log_test_bmarks));
270     if (!log_test_bmarks) {
271         MODLOG_INFO(LOG_MODULE_DEFAULT,
272                     "Leaving log_test log bookmarks unallocated\n");
273         return;
274     }
275 
276     rc = log_fcb_init_bmarks(&log_test_fcb, log_test_bmarks,
277                              log_test_fcb.fl_fcb.f_sector_cnt +
278                              MYNEWT_VAL(LOG_FCB_NUM_ABS_BOOKMARKS),
279                              true);

@kasjer
Copy link
Contributor

kasjer commented Feb 27, 2025

@vrahane in your logs bookmarks look ok, in my case first entry looks strange:

1102179 0: index:0 entry: 20007d28 fa: 0 fe_elem_off: 0

This strange element at the beginning is always there. I have not checked why it's there but it probably could explain why sector bookmarks are not used

@vrahane
Copy link
Contributor Author

vrahane commented Feb 27, 2025

@kasjer it seems fcbp->f_sector_cnt = sector_count - 1; might be causing an issue. In my FCB init function, its set to the sector count.

@vrahane
Copy link
Contributor Author

vrahane commented Feb 27, 2025

I also tried with 6 absolute bookmarks. It works fine.

@kasjer
Copy link
Contributor

kasjer commented Feb 27, 2025

@kasjer it seems fcbp->f_sector_cnt = sector_count - 1; might be causing an issue. In my FCB init function, its set to the sector count.

Yes, after correction to sector_count measured times are fast as expected

@vrahane
Copy link
Contributor Author

vrahane commented Feb 27, 2025

I am curious what timings do you see on your device ?

@vrahane vrahane added the LOGS label Feb 28, 2025
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.

3 participants