Skip to content

Commit ceb6f2e

Browse files
committed
Rework flash flush so it preserves the cache
This should make filesystem writes quicker and cause less heap churn.
1 parent a5520f8 commit ceb6f2e

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

ports/atmel-samd/supervisor/internal_flash.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ uint32_t supervisor_flash_get_block_count(void) {
7676
void supervisor_flash_flush(void) {
7777
}
7878

79+
void supervisor_flash_release_cache(void) {
80+
}
81+
7982
void flash_flush(void) {
8083
supervisor_flash_flush();
8184
}

ports/nrf/supervisor/internal_flash.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ void supervisor_flash_flush(void) {
137137
_flash_page_addr = NO_CACHE;
138138
}
139139

140+
void supervisor_flash_release_cache(void) {
141+
}
142+
140143
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
141144
// Must write out anything in cache before trying to read.
142145
supervisor_flash_flush();

supervisor/flash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
void supervisor_flash_init(void);
4141
uint32_t supervisor_flash_get_block_size(void);
4242
uint32_t supervisor_flash_get_block_count(void);
43-
void supervisor_flash_flush(void);
4443

4544
// these return 0 on success, non-zero on error
4645
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
@@ -49,5 +48,6 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num,
4948
struct _fs_user_mount_t;
5049
void supervisor_flash_init_vfs(struct _fs_user_mount_t *vfs);
5150
void supervisor_flash_flush(void);
51+
void supervisor_flash_release_cache(void);
5252

5353
#endif // MICROPY_INCLUDED_SUPERVISOR_FLASH_H

supervisor/shared/external_flash/external_flash.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ uint32_t supervisor_flash_get_block_count(void) {
272272
// Flush the cache that was written to the scratch portion of flash. Only used
273273
// when ram is tight.
274274
static bool flush_scratch_flash(void) {
275+
if (current_sector == NO_SECTOR_LOADED) {
276+
return true;
277+
}
275278
// First, copy out any blocks that we haven't touched from the sector we've
276279
// cached.
277280
bool copy_to_scratch_ok = true;
@@ -360,9 +363,25 @@ static bool allocate_ram_cache(void) {
360363
return success;
361364
}
362365

366+
static void release_ram_cache(void) {
367+
if (supervisor_cache != NULL) {
368+
free_memory(supervisor_cache);
369+
supervisor_cache = NULL;
370+
} else {
371+
m_free(MP_STATE_VM(flash_ram_cache));
372+
}
373+
MP_STATE_VM(flash_ram_cache) = NULL;
374+
}
375+
363376
// Flush the cached sector from ram onto the flash. We'll free the cache unless
364377
// keep_cache is true.
365378
static bool flush_ram_cache(bool keep_cache) {
379+
if (current_sector == NO_SECTOR_LOADED) {
380+
if (!keep_cache) {
381+
release_ram_cache();
382+
}
383+
return true;
384+
}
366385
// First, copy out any blocks that we haven't touched from the sector
367386
// we've cached. If we don't do this we'll erase the data during the sector
368387
// erase below.
@@ -403,22 +422,13 @@ static bool flush_ram_cache(bool keep_cache) {
403422
}
404423
// We're done with the cache for now so give it back.
405424
if (!keep_cache) {
406-
if (supervisor_cache != NULL) {
407-
free_memory(supervisor_cache);
408-
supervisor_cache = NULL;
409-
} else {
410-
m_free(MP_STATE_VM(flash_ram_cache));
411-
}
412-
MP_STATE_VM(flash_ram_cache) = NULL;
425+
release_ram_cache();
413426
}
414427
return true;
415428
}
416429

417430
// Delegates to the correct flash flush method depending on the existing cache.
418431
static void spi_flash_flush_keep_cache(bool keep_cache) {
419-
if (current_sector == NO_SECTOR_LOADED) {
420-
return;
421-
}
422432
#ifdef MICROPY_HW_LED_MSC
423433
port_pin_set_output_level(MICROPY_HW_LED_MSC, true);
424434
#endif
@@ -436,9 +446,11 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
436446
#endif
437447
}
438448

439-
// External flash function used. If called externally we assume we won't need
440-
// the cache after.
441449
void supervisor_flash_flush(void) {
450+
spi_flash_flush_keep_cache(true);
451+
}
452+
453+
void supervisor_flash_release_cache(void) {
442454
spi_flash_flush_keep_cache(false);
443455
}
444456

@@ -502,7 +514,7 @@ bool external_flash_write_block(const uint8_t *data, uint32_t block) {
502514
return write_flash(address, data, FILESYSTEM_BLOCK_SIZE);
503515
}
504516
if (current_sector != NO_SECTOR_LOADED) {
505-
spi_flash_flush_keep_cache(true);
517+
supervisor_flash_flush();
506518
}
507519
if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) {
508520
erase_sector(flash_device->total_size - SPI_FLASH_ERASE_SIZE);

supervisor/shared/filesystem.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ volatile bool filesystem_flush_requested = false;
4242

4343
void filesystem_background(void) {
4444
if (filesystem_flush_requested) {
45-
filesystem_flush();
45+
filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
46+
// Flush but keep caches
47+
supervisor_flash_flush();
4648
filesystem_flush_requested = false;
4749
}
4850
}
@@ -118,6 +120,8 @@ void filesystem_flush(void) {
118120
// Reset interval before next flush.
119121
filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS;
120122
supervisor_flash_flush();
123+
// Don't keep caches because this is called when starting or stopping the VM.
124+
supervisor_flash_release_cache();
121125
}
122126

123127
void filesystem_set_internal_writable_by_usb(bool writable) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy