ACK: [PATCH] lib: fwts_alloc: fix low 32 bit memory allocator (LP: #1295849)

IvanHu ivan.hu at canonical.com
Mon Mar 24 08:21:43 UTC 2014


On 03/22/2014 05:53 AM, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> The original mmap allocator made x86 specific assumptions about
> memory mappings.  Re-work the low memory allocator to try to find
> a free mapping under the 2GB 32 bit threshold by always examining
> the first mapping for the procss and either using this if it is below
> 2GB or chosing 2GB less the mapping size.  This is also more efficient
> too.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
>   src/lib/src/fwts_alloc.c | 40 +++++++++++++++++++++++++++++++++++++---
>   1 file changed, 37 insertions(+), 3 deletions(-)
>
> diff --git a/src/lib/src/fwts_alloc.c b/src/lib/src/fwts_alloc.c
> index 57ece72..9610159 100644
> --- a/src/lib/src/fwts_alloc.c
> +++ b/src/lib/src/fwts_alloc.c
> @@ -46,7 +46,9 @@ typedef struct {
>   	unsigned int magic;
>   } fwts_mmap_header;
>
> -#define LIMIT_2GB	0x80000000ULL
> +#define CHUNK_SIZE	(8192)		/* page plus loads of slack */
> +#define LIMIT_2GB	(0x80000000ULL)
> +#define LIMIT_START	(0x00010000ULL)
>
>   #ifndef MAP_32BIT
>   /*
> @@ -62,6 +64,7 @@ static void *fwts_low_mmap(const size_t requested_size)
>   	void *addr_start;
>   	void *addr_end;
>   	void *last_addr_end = NULL;
> +	void *first_addr_start = NULL;
>   	void *ret = MAP_FAILED;
>
>   	if (requested_size == 0)	/* Illegal */
> @@ -74,6 +77,35 @@ static void *fwts_low_mmap(const size_t requested_size)
>   		sscanf(buffer, "%p-%p %*s %*x %*s %*u %s",
>   			&addr_start, &addr_end, pathname);
>
> +		/*
> +		 *  Try and allocate under first mmap'd address space
> +		 */
> +		if ((first_addr_start == NULL) &&
> +		    (addr_start > (void*)LIMIT_START)) {
> +			size_t sz = (requested_size + CHUNK_SIZE) & ~(CHUNK_SIZE - 1);
> +			void *addr = addr_start - sz;
> +
> +			/*
> +			 * If addr is over the 2GB limit and we know
> +			 * that this is the first mapping then we should
> +			 * be able to map a region below the 2GB limit as
> +			 * nothing is already mapped there
> +			 */
> +			if (addr > (void*)LIMIT_2GB)
> +				addr = (void*)LIMIT_2GB - sz;
> +
> +			ret = mmap(addr, requested_size, PROT_READ | PROT_WRITE,
> +				MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
> +			if (ret != MAP_FAILED)
> +				break;	/* Success! */
> +
> +			first_addr_start = addr_start;
> +		}
> +
> +		/*
> +		 *  No allocation yet, so try now to squeeze one
> +		 *  in between already mapped regions
> +		 */
>   		if ((last_addr_end != NULL) &&
>   		    (last_addr_end < (void*)LIMIT_2GB)) {
>   			if ((addr_start - last_addr_end) > (ptrdiff_t)requested_size) {
> @@ -85,9 +117,11 @@ static void *fwts_low_mmap(const size_t requested_size)
>   			}
>   		}
>
> -		/* We really don't want to mmap at the end of the heap
> +		/*
> +		 * We really don't want to mmap at the end of the heap
>   		 * and if we've reached the stack we've gone too far so
> -		 * abort */
> +		 * abort
> +		 */
>   		if ((strncmp("[heap]", pathname, 6) == 0) ||
>   		    (strncmp("[stack]", pathname, 7) == 0)) {
>   			ret = MAP_FAILED;
>

Acked-by: Ivan Hu <ivan.hu at canonical.com>




More information about the fwts-devel mailing list