[PATCH] ION: Sys_heap: Add cached pool to spead up cached buffer alloc

Chen Feng puck.chen at hisilicon.com
Mon May 9 06:46:06 UTC 2016


Sorry,the order here is not right, please ignore this patch.

I will RESEND it.

On 2016/5/9 14:24, Chen Feng wrote:
> Add ion cached pool in system heap.
> 
> Signed-off-by: Chen Feng <puck.chen at hisilicon.com>
> Signed-off-by: Xia  Qing <saberlily.xia at hisilicon.com>
> ---
>  drivers/staging/android/ion/ion_system_heap.c | 120 +++++++++++++++++---------
>  1 file changed, 79 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
> index b69dfc7..5b7e5b0 100644
> --- a/drivers/staging/android/ion/ion_system_heap.c
> +++ b/drivers/staging/android/ion/ion_system_heap.c
> @@ -49,7 +49,8 @@ static inline unsigned int order_to_size(int order)
>  
>  struct ion_system_heap {
>  	struct ion_heap heap;
> -	struct ion_page_pool *pools[0];
> +	struct ion_page_pool *uncached_pools[0];
> +	struct ion_page_pool *cached_pools[0];
>  };
>  
>  static struct page *alloc_buffer_page(struct ion_system_heap *heap,
> @@ -57,39 +58,36 @@ static struct page *alloc_buffer_page(struct ion_system_heap *heap,
>  				      unsigned long order)
>  {
>  	bool cached = ion_buffer_cached(buffer);
> -	struct ion_page_pool *pool = heap->pools[order_to_index(order)];
> +	struct ion_page_pool *pool;
>  	struct page *page;
>  
> -	if (!cached) {
> -		page = ion_page_pool_alloc(pool);
> -	} else {
> -		gfp_t gfp_flags = low_order_gfp_flags;
> -
> -		if (order > 4)
> -			gfp_flags = high_order_gfp_flags;
> -		page = alloc_pages(gfp_flags | __GFP_COMP, order);
> -		if (!page)
> -			return NULL;
> -		ion_pages_sync_for_device(NULL, page, PAGE_SIZE << order,
> -						DMA_BIDIRECTIONAL);
> -	}
> +	if (!cached)
> +		pool = heap->uncached_pools[order_to_index(order)];
> +	else
> +		pool = heap->cached_pools[order_to_index(order)];
>  
> +	page = ion_page_pool_alloc(pool);
>  	return page;
>  }
>  
>  static void free_buffer_page(struct ion_system_heap *heap,
>  			     struct ion_buffer *buffer, struct page *page)
>  {
> +	struct ion_page_pool *pool;
>  	unsigned int order = compound_order(page);
>  	bool cached = ion_buffer_cached(buffer);
>  
> -	if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE)) {
> -		struct ion_page_pool *pool = heap->pools[order_to_index(order)];
> -
> -		ion_page_pool_free(pool, page);
> -	} else {
> +	if (buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE) {
>  		__free_pages(page, order);
> +		return;
>  	}
> +
> +	if (!cached)
> +		pool = heap->uncached_pools[order_to_index(order)];
> +	else
> +		pool = heap->cached_pools[order_to_index(order)];
> +
> +	ion_page_pool_free(pool, page);
>  }
>  
>  
> @@ -224,9 +222,11 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
>  		only_scan = 1;
>  
>  	for (i = 0; i < num_orders; i++) {
> -		struct ion_page_pool *pool = sys_heap->pools[i];
> +		struct ion_page_pool *pool = sys_heap->uncached_pools[i];
>  
> -		nr_freed = ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
> +		nr_freed += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
> +		pool = sys_heap->cached_pools[i];
> +		nr_freed += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
>  		nr_total += nr_freed;
>  
>  		if (!only_scan) {
> @@ -259,27 +259,69 @@ static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
>  							struct ion_system_heap,
>  							heap);
>  	int i;
> +	struct ion_page_pool *pool;
>  
>  	for (i = 0; i < num_orders; i++) {
> -		struct ion_page_pool *pool = sys_heap->pools[i];
> +		pool = sys_heap->uncached_pools[i];
>  
> -		seq_printf(s, "%d order %u highmem pages in pool = %lu total\n",
> +		seq_printf(s, "%d order %u highmem pages uncached %lu total\n",
>  			   pool->high_count, pool->order,
>  			   (PAGE_SIZE << pool->order) * pool->high_count);
> -		seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n",
> +		seq_printf(s, "%d order %u lowmem pages uncached %lu total\n",
>  			   pool->low_count, pool->order,
>  			   (PAGE_SIZE << pool->order) * pool->low_count);
>  	}
> +
> +	for (i = 0; i < num_orders; i++) {
> +		pool = sys_heap->cached_pools[i];
> +
> +		seq_printf(s, "%d order %u highmem pages cached %lu total\n",
> +			   pool->high_count, pool->order,
> +			   (PAGE_SIZE << pool->order) * pool->high_count);
> +		seq_printf(s, "%d order %u lowmem pages cached %lu total\n",
> +			   pool->low_count, pool->order,
> +			   (PAGE_SIZE << pool->order) * pool->low_count);
> +	}
> +	return 0;
> +}
> +
> +static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
> +{
> +	int i;
> +
> +	for (i = 0; i < num_orders; i++)
> +		if (pools[i])
> +			ion_page_pool_destroy(pools[i]);
> +}
> +
> +static int ion_system_heap_create_pools(struct ion_page_pool **pools)
> +{
> +	int i;
> +	gfp_t gfp_flags = low_order_gfp_flags;
> +
> +	for (i = 0; i < num_orders; i++) {
> +		struct ion_page_pool *pool;
> +
> +		if (orders[i])
> +			gfp_flags = high_order_gfp_flags;
> +
> +		pool = ion_page_pool_create(gfp_flags, orders[i]);
> +		if (!pool)
> +			goto err_create_pool;
> +		pools[i] = pool;
> +	}
>  	return 0;
> +err_create_pool:
> +	ion_system_heap_destroy_pools(pools);
> +	return -ENOMEM;
>  }
>  
>  struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
>  {
>  	struct ion_system_heap *heap;
> -	int i;
>  
>  	heap = kzalloc(sizeof(struct ion_system_heap) +
> -			sizeof(struct ion_page_pool *) * num_orders,
> +			sizeof(struct ion_page_pool *) * num_orders * 2,
>  			GFP_KERNEL);
>  	if (!heap)
>  		return ERR_PTR(-ENOMEM);
> @@ -287,24 +329,18 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
>  	heap->heap.type = ION_HEAP_TYPE_SYSTEM;
>  	heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
>  
> -	for (i = 0; i < num_orders; i++) {
> -		struct ion_page_pool *pool;
> -		gfp_t gfp_flags = low_order_gfp_flags;
> +	if (ion_system_heap_create_pools(heap->uncached_pools))
> +		goto destroy_pools;
>  
> -		if (orders[i] > 4)
> -			gfp_flags = high_order_gfp_flags;
> -		pool = ion_page_pool_create(gfp_flags, orders[i]);
> -		if (!pool)
> -			goto destroy_pools;
> -		heap->pools[i] = pool;
> -	}
> +	if (ion_system_heap_create_pools(heap->cached_pools))
> +		goto destroy_uncached_pools;
>  
>  	heap->heap.debug_show = ion_system_heap_debug_show;
>  	return &heap->heap;
>  
> +destroy_uncached_pools:
> +	ion_system_heap_destroy_pools(heap->uncached_pools);
>  destroy_pools:
> -	while (i--)
> -		ion_page_pool_destroy(heap->pools[i]);
>  	kfree(heap);
>  	return ERR_PTR(-ENOMEM);
>  }
> @@ -316,8 +352,10 @@ void ion_system_heap_destroy(struct ion_heap *heap)
>  							heap);
>  	int i;
>  
> -	for (i = 0; i < num_orders; i++)
> -		ion_page_pool_destroy(sys_heap->pools[i]);
> +	for (i = 0; i < num_orders; i++) {
> +		ion_page_pool_destroy(sys_heap->uncached_pools[i]);
> +		ion_page_pool_destroy(sys_heap->uncached_pools[i]);
> +	}
>  	kfree(sys_heap);
>  }
>  
> 



More information about the devel mailing list