summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2017-03-22 16:11:17 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2017-03-31 13:57:46 +0200
commiteee08770763c327385650c8b7b343dcc590875d0 (patch)
tree50b53762f5844977e92a3e02eb600e135e7788b5
parentfa4ef25aa012bf0b11a0d7b89798ee5275931302 (diff)
downloaddt-utils-eee08770763c327385650c8b7b343dcc590875d0.tar.gz
state: backend_circular: Read whole PEB
When the circular backend searches for the last page written in the eraseblock, it iterates backwards pagewise from the end of the block. This is ok for NAND flash, but on NOR flash, which does not have pages, the code ends up iterating bytewise backwards, calling into mtd each time. This is very time consuming, so optimize this by reading the whole eraseblock once and just iterate over the buffer in memory. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r--src/barebox-state/backend_bucket_circular.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/src/barebox-state/backend_bucket_circular.c b/src/barebox-state/backend_bucket_circular.c
index 0bce900..53c2aae 100644
--- a/src/barebox-state/backend_bucket_circular.c
+++ b/src/barebox-state/backend_bucket_circular.c
@@ -379,26 +379,24 @@ static int state_backend_bucket_circular_init(
int sub_offset;
uint32_t written_length = 0;
uint8_t *buf;
+ int ret;
- buf = xmalloc(circ->writesize);
+ buf = xmalloc(circ->max_size);
if (!buf)
return -ENOMEM;
+ ret = state_mtd_peb_read(circ, buf, 0, circ->max_size);
+ if (ret && ret != -EUCLEAN)
+ return ret;
+
for (sub_offset = circ->max_size - circ->writesize; sub_offset >= 0;
sub_offset -= circ->writesize) {
- int ret;
-
- ret = state_mtd_peb_read(circ, buf, sub_offset,
- circ->writesize);
- if (ret && ret != -EUCLEAN)
- return ret;
-
- ret = mtd_buf_all_ff(buf, circ->writesize);
+ ret = mtd_buf_all_ff(buf + sub_offset, circ->writesize);
if (!ret) {
struct state_backend_storage_bucket_circular_meta *meta;
meta = (struct state_backend_storage_bucket_circular_meta *)
- (buf + circ->writesize - sizeof(*meta));
+ (buf + sub_offset + circ->writesize - sizeof(*meta));
if (meta->magic != circular_magic)
written_length = 0;