diff options
author | Yixun Lan <yixun.lan@gmail.com> | 2016-03-01 12:48:09 +0800 |
---|---|---|
committer | Ying-Chun Liu (PaulLiu) <paulliu@debian.org> | 2016-03-02 13:30:44 +0800 |
commit | 2fd651604a6dbc8d707470b8fe08982790aa7734 (patch) | |
tree | 3e0994de42a116a72ed7862e6932c915f186049c /common/aboot.c | |
parent | 9986a91bb86649daa7826d96555671f73a788f6c (diff) |
aboot: improve the buffer allocation schemebubblegum96
we try several granularity to make the allocation failure less happen
1) we first will try to allocate buffer as max order of
CONFIG_FILL_BUFF_MAX_SIZE, eg 8192 blocks for SZ_4M if blksz = 512byte
2) if failure occur, we will try to allocate 8192/2=4096 blocks
3) still fail to allocate, we will try size 4096/2=2048 blocks
..
4) untill the allocation success ( the min buffer = 1 block)
Signed-off-by: Yixun Lan <yixun.lan@gmail.com>
Diffstat (limited to 'common/aboot.c')
-rw-r--r-- | common/aboot.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/common/aboot.c b/common/aboot.c index 1cfc606dd4..54374c9f17 100644 --- a/common/aboot.c +++ b/common/aboot.c @@ -41,27 +41,32 @@ #include <part.h> #include <sparse_format.h> #include <linux/sizes.h> +#include <linux/kernel.h> -#ifndef CONFIG_FILL_BUFF_SIZE -#define CONFIG_FILL_BUFF_SIZE SZ_4M +#ifndef CONFIG_FILL_BUFF_MAX_SIZE +#define CONFIG_FILL_BUFF_MAX_SIZE SZ_4M #endif static int write_fill_multi_blks(block_dev_desc_t *dev_desc, disk_partition_t *info, lbaint_t *blk, lbaint_t blkcnt, uint32_t fill_val) { - int i, size;; + int i, size, order; uint32_t *fill_buf; lbaint_t blks, fill_cnt, written_blks = 0; - fill_cnt = CONFIG_FILL_BUFF_SIZE / info->blksz; - lbaint_t quot = blkcnt / fill_cnt; - lbaint_t remd = blkcnt % fill_cnt; - - size = blkcnt > fill_cnt ? CONFIG_FILL_BUFF_SIZE : (blkcnt * info->blksz); + order = get_order(MIN(CONFIG_FILL_BUFF_MAX_SIZE, (blkcnt * info->blksz)), + info->blksz); - fill_buf = (uint32_t *) memalign(ARCH_DMA_MINALIGN, + while(order >= 0) { + size = info->blksz << order; + fill_buf = (uint32_t *) memalign(ARCH_DMA_MINALIGN, ROUNDUP(size, ARCH_DMA_MINALIGN)); + if (fill_buf) + break; + + order--; + } if (!fill_buf) { fastboot_fail( @@ -69,6 +74,13 @@ static int write_fill_multi_blks(block_dev_desc_t *dev_desc, return -1; } + fill_cnt = 0x1 << order; + lbaint_t quot = blkcnt / fill_cnt; + lbaint_t remd = blkcnt % fill_cnt; + + if (blkcnt < fill_cnt) + size = blkcnt * info->blksz; + for (i = 0; i < (size / sizeof(fill_val)); i++) fill_buf[i] = fill_val; @@ -237,7 +249,9 @@ void write_sparse_image(block_dev_desc_t *dev_desc, fill_val = *(uint32_t *)data; data = (char *) data + sizeof(uint32_t); - write_fill_multi_blks(dev_desc, info, &blk, blkcnt, fill_val); + if (write_fill_multi_blks(dev_desc, info, &blk, + blkcnt, fill_val) < 0) + return; bytes_written += blkcnt * info->blksz; total_blocks += chunk_data_sz / sparse_header->blk_sz; |