[Skiboot] [PATCH v2 1/5] libflash/ipmi-hiomap: Fix blocks count issue
Andrew Jeffery
andrew at aj.id.au
Tue Apr 9 10:53:52 AEST 2019
On Mon, 8 Apr 2019, at 15:35, Vasant Hegde wrote:
> We convert data size to block count and pass block count to BMC.
> If data size is not block aligned then we endup sending block count
> less than actual data. BMC will write partial data to flash memory.
>
> Sample log :
> [ 594.388458416,7] HIOMAP: Marked flash dirty at 0x42010 for 8
> [ 594.398756487,7] HIOMAP: Flushed writes
> [ 594.409596439,7] HIOMAP: Marked flash dirty at 0x42018 for 3970
> [ 594.419897507,7] HIOMAP: Flushed writes
>
> In this case HIOMAP sent data with block count=0 and hence BMC didn't
> flush data to flash.
>
> Lets fix this issue by adjusting block count before sending it to BMC.
>
> Cc: Andrew Jeffery <andrew at aj.id.au>
> Cc: skiboot-stable at lists.ozlabs.org
> Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
Reviewed-by: Andrew Jeffery <andrew at aj.id.au>
Thanks for cleaning up my mess :)
> ---
> libflash/ipmi-hiomap.c | 21 ++++++++++++++++++---
> 1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/libflash/ipmi-hiomap.c b/libflash/ipmi-hiomap.c
> index 56492fa87..9174eabd2 100644
> --- a/libflash/ipmi-hiomap.c
> +++ b/libflash/ipmi-hiomap.c
> @@ -49,6 +49,21 @@ static inline uint16_t bytes_to_blocks(struct
> ipmi_hiomap *ctx, uint32_t bytes)
> return bytes >> ctx->block_size_shift;
> }
>
> +static inline uint16_t bytes_to_blocks_align_up(struct ipmi_hiomap
> *ctx,
> + uint32_t pos, uint32_t len)
> +{
> + uint32_t block_size = 1 << ctx->block_size_shift;
> + uint32_t delta = pos & (block_size - 1);
> + uint32_t aligned = ALIGN_UP((len + delta), block_size);
> + uint32_t blocks = aligned >> ctx->block_size_shift;
> + /* Our protocol can handle block count < sizeof(u16) */
> + uint32_t mask = ((1 << 16) - 1);
> +
> + assert(!(blocks & ~mask));
> +
> + return blocks & mask;
> +}
> +
> /* Call under ctx->lock */
> static int hiomap_protocol_ready(struct ipmi_hiomap *ctx)
> {
> @@ -321,7 +336,7 @@ static int hiomap_window_move(struct ipmi_hiomap
> *ctx, uint8_t command,
>
> range = (struct hiomap_v2_range *)&req[2];
> range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
> - range->size = cpu_to_le16(bytes_to_blocks(ctx, len));
> + range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, len));
>
> msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
> bmc_platform->sw->ipmi_oem_hiomap_cmd,
> @@ -384,7 +399,7 @@ static int hiomap_mark_dirty(struct ipmi_hiomap
> *ctx, uint64_t offset,
> pos = offset - ctx->current.cur_pos;
> range = (struct hiomap_v2_range *)&req[2];
> range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
> - range->size = cpu_to_le16(bytes_to_blocks(ctx, size));
> + range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, size));
>
> msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
> bmc_platform->sw->ipmi_oem_hiomap_cmd,
> @@ -494,7 +509,7 @@ static int hiomap_erase(struct ipmi_hiomap *ctx,
> uint64_t offset,
> pos = offset - ctx->current.cur_pos;
> range = (struct hiomap_v2_range *)&req[2];
> range->offset = cpu_to_le16(bytes_to_blocks(ctx, pos));
> - range->size = cpu_to_le16(bytes_to_blocks(ctx, size));
> + range->size = cpu_to_le16(bytes_to_blocks_align_up(ctx, pos, size));
>
> msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE,
> bmc_platform->sw->ipmi_oem_hiomap_cmd,
> --
> 2.14.3
>
>
More information about the Skiboot
mailing list