diff options
author | Jens Wiklander <jens.wiklander@linaro.org> | 2018-03-09 17:13:24 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2018-04-03 18:07:07 +0200 |
commit | 0e3f6d6bb28b63f15541b397b5bdaed563bbfab7 (patch) | |
tree | 1128162fe70e69024135420168ba0c7a81eaf2c3 /core/tee | |
parent | 820042a5ca744ced2b90364313bc002d3b8e4a2e (diff) |
core: REE FS: temporary block allocation
Large memory allocations with malloc() can fail due to a fragmented
heap. This is especially a problem when configured with pager as the
heap is kept as small as possible in that configuration for obvious
reasons.
This patch allocates the temporary block needed for reading and writing
in REE FS tee_pager_alloc() instead when the pager is enabled.
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/tee')
-rw-r--r-- | core/tee/tee_ree_fs.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/core/tee/tee_ree_fs.c b/core/tee/tee_ree_fs.c index 60d6e0e1..46578b55 100644 --- a/core/tee/tee_ree_fs.c +++ b/core/tee/tee_ree_fs.c @@ -8,6 +8,7 @@ #include <kernel/panic.h> #include <kernel/thread.h> #include <mm/core_memprot.h> +#include <mm/tee_pager.h> #include <optee_msg_supplicant.h> #include <stdio.h> #include <stdlib.h> @@ -48,7 +49,41 @@ static int pos_to_block_num(int position) static struct mutex ree_fs_mutex = MUTEX_INITIALIZER; +#ifdef CFG_WITH_PAGER +static void *ree_fs_tmp_block; +static bool ree_fs_tmp_block_busy; +static void *get_tmp_block(void) +{ + assert(!ree_fs_tmp_block_busy); + if (!ree_fs_tmp_block) + ree_fs_tmp_block = tee_pager_alloc(BLOCK_SIZE, + TEE_MATTR_LOCKED); + + if (ree_fs_tmp_block) + ree_fs_tmp_block_busy = true; + + return ree_fs_tmp_block; +} + +static void put_tmp_block(void *tmp_block) +{ + assert(ree_fs_tmp_block_busy); + assert(tmp_block == ree_fs_tmp_block); + tee_pager_release_phys(tmp_block, BLOCK_SIZE); + ree_fs_tmp_block_busy = false; +} +#else +static void *get_tmp_block(void) +{ + return malloc(BLOCK_SIZE); +} + +static void put_tmp_block(void *tmp_block) +{ + free(tmp_block); +} +#endif static TEE_Result out_of_place_write(struct tee_fs_fd *fdp, size_t pos, const void *buf, size_t len) @@ -61,7 +96,7 @@ static TEE_Result out_of_place_write(struct tee_fs_fd *fdp, size_t pos, uint8_t *block; struct tee_fs_htree_meta *meta = tee_fs_htree_get_meta(fdp->ht); - block = malloc(BLOCK_SIZE); + block = get_tmp_block(); if (!block) return TEE_ERROR_OUT_OF_MEMORY; @@ -105,7 +140,8 @@ static TEE_Result out_of_place_write(struct tee_fs_fd *fdp, size_t pos, } exit: - free(block); + if (block) + put_tmp_block(block); return res; } @@ -303,7 +339,7 @@ static TEE_Result ree_fs_read_primitive(struct tee_file_handle *fh, size_t pos, start_block_num = pos_to_block_num(pos); end_block_num = pos_to_block_num(pos + remain_bytes - 1); - block = malloc(BLOCK_SIZE); + block = get_tmp_block(); if (!block) { res = TEE_ERROR_OUT_OF_MEMORY; goto exit; @@ -330,7 +366,8 @@ static TEE_Result ree_fs_read_primitive(struct tee_file_handle *fh, size_t pos, } res = TEE_SUCCESS; exit: - free(block); + if (block) + put_tmp_block(block); return res; } |