Skip to content

Commit

Permalink
external/gard: Clear entire guard partition instead of entry by entry
Browse files Browse the repository at this point in the history
When using the current implementation of the gard tool to ecc clear the
entire GUARD partition it is done one gard record at a time. While this
may be ok when accessing the actual flash this is very slow when done
from the host over the mbox protocol (on the order of 4 minutes) because
the bmc side is required to do many read, erase, writes under the hood.

Fix this by rewriting the gard tool reset_partition() function. Now we
allocate all the erased guard entries and (if required) apply ecc to the
entire buffer. Then we can do one big erase and write of the entire
partition. This reduces the time to clear the guard partition to on the
order of 4 seconds.

Reported-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Reviewed-by: Cyril Bur <cyril.bur@au1.ibm.com
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
sjitindarsingh authored and stewartsmith committed Oct 6, 2017
1 parent 25e041a commit b987d1a
Showing 1 changed file with 18 additions and 11 deletions.
29 changes: 18 additions & 11 deletions external/gard/gard.c
Expand Up @@ -454,24 +454,31 @@ static int do_clear_i(struct gard_ctx *ctx, int pos, struct gard_record *gard, v

static int reset_partition(struct gard_ctx *ctx)
{
int i, rc;
struct gard_record gard;
memset(&gard, 0xFF, sizeof(gard));
int len, num_entries, rc = 0;
struct gard_record *gard;

num_entries = ctx->gard_data_len / sizeof_gard(ctx);
len = num_entries * sizeof(*gard);
gard = malloc(len);
if (!gard) {
return FLASH_ERR_MALLOC_FAILED;
}
memset(gard, 0xFF, len);

rc = blocklevel_smart_erase(ctx->bl, ctx->gard_data_pos, ctx->gard_data_len);
if (rc) {
fprintf(stderr, "Couldn't erase the gard partition. Bailing out\n");
return rc;
goto out;
}
for (i = 0; i + sizeof_gard(ctx) < ctx->gard_data_len; i += sizeof_gard(ctx)) {
rc = blocklevel_write(ctx->bl, ctx->gard_data_pos + i, &gard, sizeof(gard));
if (rc) {
fprintf(stderr, "Couldn't reset the entire gard partition. Bailing out\n");
return rc;
}
rc = blocklevel_write(ctx->bl, ctx->gard_data_pos, gard, len);
if (rc) {
fprintf(stderr, "Couldn't reset the entire gard partition. Bailing out\n");
goto out;
}

return 0;
out:
free(gard);
return rc;
}

static int do_clear(struct gard_ctx *ctx, int argc, char **argv)
Expand Down

0 comments on commit b987d1a

Please sign in to comment.