Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7acf369 authored by Laura Abbott's avatar Laura Abbott
Browse files

ion: Drop cache operation after zeroing



At one time, the zeroing algorithm used a mixture of
cached and uncached mappings which necessitated an extra
cache operation afterwards. The zeroing algorithm has been
simplified so the cache operation is no longer required if
the mapping used for zeroing matches the cache status of
the buffer (cached or not). Remove the cache operation and
use appropriate page protections instead.

Change-Id: I7d3596ed503811818782e77a0f3f7f63b1456d70
Signed-off-by: default avatarLaura Abbott <lauraa@codeaurora.org>
parent e5b516ca
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool)
		return NULL;

	if (pool->gfp_mask & __GFP_ZERO)
		if (msm_ion_heap_high_order_page_zero(page, pool->order))
		if (msm_ion_heap_high_order_page_zero(page, pool->order,
							pool->cached))
			goto error_free_pages;

	return page;
+4 −2
Original line number Diff line number Diff line
@@ -253,9 +253,10 @@ int ion_heap_map_user(struct ion_heap *, struct ion_buffer *,
			struct vm_area_struct *);
int ion_heap_buffer_zero(struct ion_buffer *buffer);

int msm_ion_heap_high_order_page_zero(struct page *page, int order);
int msm_ion_heap_high_order_page_zero(struct page *page, int order,
					bool cached);
int msm_ion_heap_buffer_zero(struct ion_buffer *buffer);
int msm_ion_heap_pages_zero(struct page **pages, int num_pages);
int msm_ion_heap_pages_zero(struct page **pages, int num_pages, pgprot_t prot);
int msm_ion_heap_alloc_pages_mem(struct pages_mem *pages_mem);
void msm_ion_heap_free_pages_mem(struct pages_mem *pages_mem);

@@ -399,6 +400,7 @@ struct ion_page_pool {
	gfp_t gfp_mask;
	unsigned int order;
	struct plist_node list;
	bool cached;
};

struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);
+9 −4
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
	unsigned int max_order = orders[0];
	struct pages_mem data;
	unsigned int sz;
	pgprot_t pgprot = buffer->flags & ION_FLAG_CACHED ? PAGE_KERNEL :
					pgprot_writecombine(PAGE_KERNEL);

	if (align > PAGE_SIZE)
		return -EINVAL;
@@ -274,7 +276,8 @@ static int ion_system_heap_allocate(struct ion_heap *heap,

	} while (sg);

	ret = msm_ion_heap_pages_zero(data.pages, data.size >> PAGE_SHIFT);
	ret = msm_ion_heap_pages_zero(data.pages, data.size >> PAGE_SHIFT,
					pgprot);
	if (ret) {
		pr_err("Unable to zero pages\n");
		goto err_free_sg2;
@@ -431,7 +434,8 @@ static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
 * nothing. If it succeeds you'll eventually need to use
 * ion_system_heap_destroy_pools to destroy the pools.
 */
static int ion_system_heap_create_pools(struct ion_page_pool **pools)
static int ion_system_heap_create_pools(struct ion_page_pool **pools,
						bool cached)
{
	int i;
	for (i = 0; i < num_orders; i++) {
@@ -443,6 +447,7 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools)
		pool = ion_page_pool_create(gfp_flags, orders[i]);
		if (!pool)
			goto err_create_pool;
		pool->cached = cached;
		pools[i] = pool;
	}
	return 0;
@@ -471,10 +476,10 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
	if (!heap->cached_pools)
		goto err_alloc_cached_pools;

	if (ion_system_heap_create_pools(heap->uncached_pools))
	if (ion_system_heap_create_pools(heap->uncached_pools, false))
		goto err_create_uncached_pools;

	if (ion_system_heap_create_pools(heap->cached_pools))
	if (ion_system_heap_create_pools(heap->cached_pools, true))
		goto err_create_cached_pools;

	heap->heap.debug_show = ion_system_heap_debug_show;
+18 −9
Original line number Diff line number Diff line
@@ -804,7 +804,7 @@ long msm_ion_custom_ioctl(struct ion_client *client,
 * and thus caller is responsible for handling any cache maintenance
 * operations needed.
 */
int msm_ion_heap_pages_zero(struct page **pages, int num_pages)
int msm_ion_heap_pages_zero(struct page **pages, int num_pages, pgprot_t pgprot)
{
	int i, j, npages_to_vmap;
	void *ptr = NULL;
@@ -823,7 +823,7 @@ int msm_ion_heap_pages_zero(struct page **pages, int num_pages)
		for (j = 0; j < MAX_VMAP_RETRIES && npages_to_vmap;
			++j) {
			ptr = vmap(&pages[i], npages_to_vmap,
					VM_IOREMAP, PAGE_KERNEL);
					VM_IOREMAP, pgprot);
			if (ptr)
				break;
			else
@@ -874,22 +874,27 @@ void msm_ion_heap_free_pages_mem(struct pages_mem *pages_mem)
	pages_mem->free_fn(pages_mem->pages);
}

int msm_ion_heap_high_order_page_zero(struct page *page, int order)
int msm_ion_heap_high_order_page_zero(struct page *page, int order, bool cached)
{
	int i, ret;
	struct pages_mem pages_mem;
	int npages = 1 << order;
	pgprot_t pgprot;

	pages_mem.size = npages * PAGE_SIZE;

	if (cached)
		pgprot = PAGE_KERNEL;
	else
		pgprot = pgprot_writecombine(PAGE_KERNEL);

	if (msm_ion_heap_alloc_pages_mem(&pages_mem))
		return -ENOMEM;

	for (i = 0; i < (1 << order); ++i)
		pages_mem.pages[i] = page + i;

	ret = msm_ion_heap_pages_zero(pages_mem.pages, npages);
	dma_sync_single_for_device(NULL, page_to_phys(page), pages_mem.size,
				   DMA_BIDIRECTIONAL);
	ret = msm_ion_heap_pages_zero(pages_mem.pages, npages, pgprot);
	msm_ion_heap_free_pages_mem(&pages_mem);
	return ret;
}
@@ -900,6 +905,12 @@ int msm_ion_heap_buffer_zero(struct ion_buffer *buffer)
	struct scatterlist *sg;
	int i, j, ret = 0, npages = 0;
	struct pages_mem pages_mem;
	pgprot_t pgprot;

	if (buffer->flags & ION_FLAG_CACHED)
		pgprot = PAGE_KERNEL;
	else
		pgprot = pgprot_writecombine(PAGE_KERNEL);

	pages_mem.size = PAGE_ALIGN(buffer->size);

@@ -914,9 +925,7 @@ int msm_ion_heap_buffer_zero(struct ion_buffer *buffer)
			pages_mem.pages[npages++] = page + j;
	}

	ret = msm_ion_heap_pages_zero(pages_mem.pages, npages);
	dma_sync_sg_for_device(NULL, table->sgl, table->nents,
			       DMA_BIDIRECTIONAL);
	ret = msm_ion_heap_pages_zero(pages_mem.pages, npages, pgprot);
	msm_ion_heap_free_pages_mem(&pages_mem);
	return ret;
}