[PATCH] lib: sparse: Make CHUNK_TYPE_RAW buffer aligned
qianfan
qianfanguijin at qq.com
Mon Nov 8 03:12:53 CET 2021
在 2021/11/5 23:06, Sean Anderson 写道:
> Hi quanfan,
>
> Thanks for the patch. I had something similar in mind.
>
> On 11/5/21 1:46 AM, qianfanguijin at qq.com wrote:
>> From: qianfan Zhao <qianfanguijin at 163.com>
>>
>> CHUNK_TYPE_RAW buffer is not aligned, and flash sparse images by
>> fastboot will report "Misaligned operation" if DCACHE is enabled.
>>
>> Flashing Sparse Image
>> CACHE: Misaligned operation at range [84000028, 84001028]
>> CACHE: Misaligned operation at range [84001034, 84002034]
>> CACHE: Misaligned operation at range [8401104c, 8401304c]
>>
>> Fix it
>>
>> Signed-off-by: qianfan Zhao <qianfanguijin at 163.com>
>> ---
>> lib/image-sparse.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 45 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/image-sparse.c b/lib/image-sparse.c
>> index d80fdbbf58..1c621cd685 100644
>> --- a/lib/image-sparse.c
>> +++ b/lib/image-sparse.c
>> @@ -49,6 +49,48 @@
>>
>> static void default_log(const char *ignored, char *response) {}
>>
>> +static lbaint_t write_sparse_chunk_raw(struct sparse_storage *info,
>> + lbaint_t blk, lbaint_t blkcnt,
>> + void *data,
>> + char *response)
>> +{
>> +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
>
> Please rewrite this like
>
> if (CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
> return info->write(info, blk, blkcnt, data);
>
>> + lbaint_t n, blks = 0, aligned_buf_blks = 100;
>
> Can we try allocating info->blksz * blkcnt up front?
>
>> + uint32_t *aligned_buf = NULL;
>> +
>> + while (blkcnt > 0) {
>> + aligned_buf = (uint32_t *)
>> + memalign(ARCH_DMA_MINALIGN,
>> + ROUNDUP(
>> + info->blksz * aligned_buf_blks,
>> + ARCH_DMA_MINALIGN));
>
> I don't think we need this ROUNDUP. info->blksz is the block size of the
> underlying storage, which is at least 512. And void pointers don't need
> to be casted.
>
>> + if (!aligned_buf) {
>> + info->mssg("Malloc failed for: CHUNK_TYPE_RAW",
>> + response);
>> + return -1;
>
> return -ENOMEM;
>
> Yes, the rest of the function returns -1, but there is no reason to
> perpetuate that.
>
>> + }
>> +
>> + n = min(aligned_buf_blks, blkcnt);
>> + memcpy(aligned_buf, data, n * info->blksz);
>> +
>> + if (info->write(info, blk + blks, n, aligned_buf) != n) {
>> + free(aligned_buf);
>
> Can we reuse the buffer instead of allocating/freeing it every loop?
>
>> + return n + blks;
>> + }
>> +
>> + free(aligned_buf);
>> +
>> + data += n * info->blksz;
>> + blkcnt -= n;
>> + blks += n;
>> + }
>> +
>> + return blks;
>> +#else
>> + return info->write(info, blk, blkcnt, data);
>> +#endif
>> +}
>> +
>> int write_sparse_image(struct sparse_storage *info,
>> const char *part_name, void *data, char *response)
>> {
>> @@ -152,7 +194,9 @@ int write_sparse_image(struct sparse_storage *info,
>> return -1;
>> }
>>
>> - blks = info->write(info, blk, blkcnt, data);
>> + blks = write_sparse_chunk_raw(info, blk, blkcnt,
>> + data, response);
>> +
>> /* blks might be > blkcnt (eg. NAND bad-blocks) */
>> if (blks < blkcnt) {
>> printf("%s: %s" LBAFU " [" LBAFU "]\n",
>
> You also need to fix the error handling here. Otherwise you will get
> tuings like "Write failed, block #4294967295" on out of memory.
thanks for your's review. I had changed based on yours guide and has a
question about this error message.
What is your's test platform, nand flash? I had tested on emmc platform
and no such messages.
>
> --Sean
More information about the U-Boot
mailing list