ion_system_heap.c revision b308a7c5cfef6e0d15b8872982645313f415b229
1/*
2 * drivers/staging/android/ion/ion_system_heap.c
3 *
4 * Copyright (C) 2011 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <asm/page.h>
18#include <linux/dma-mapping.h>
19#include <linux/err.h>
20#include <linux/highmem.h>
21#include <linux/mm.h>
22#include <linux/scatterlist.h>
23#include <linux/seq_file.h>
24#include <linux/slab.h>
25#include <linux/vmalloc.h>
26#include "ion.h"
27#include "ion_priv.h"
28
29static unsigned int high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO |
30					    __GFP_NOWARN | __GFP_NORETRY |
31					    __GFP_NO_KSWAPD) & ~__GFP_WAIT;
32static unsigned int low_order_gfp_flags  = (GFP_HIGHUSER | __GFP_ZERO |
33					 __GFP_NOWARN);
34static const unsigned int orders[] = {8, 4, 0};
35static const int num_orders = ARRAY_SIZE(orders);
36static int order_to_index(unsigned int order)
37{
38	int i;
39	for (i = 0; i < num_orders; i++)
40		if (order == orders[i])
41			return i;
42	BUG();
43	return -1;
44}
45
46static unsigned int order_to_size(int order)
47{
48	return PAGE_SIZE << order;
49}
50
51struct ion_system_heap {
52	struct ion_heap heap;
53	struct ion_page_pool **pools;
54};
55
56struct page_info {
57	struct page *page;
58	unsigned int order;
59	struct list_head list;
60};
61
62static struct page *alloc_buffer_page(struct ion_system_heap *heap,
63				      struct ion_buffer *buffer,
64				      unsigned long order)
65{
66	bool cached = ion_buffer_cached(buffer);
67	bool split_pages = ion_buffer_fault_user_mappings(buffer);
68	struct ion_page_pool *pool = heap->pools[order_to_index(order)];
69	struct page *page;
70
71	if (!cached) {
72		page = ion_page_pool_alloc(pool);
73	} else {
74		gfp_t gfp_flags = low_order_gfp_flags;
75
76		if (order > 4)
77			gfp_flags = high_order_gfp_flags;
78		page = alloc_pages(gfp_flags, order);
79		if (!page)
80			return 0;
81		__dma_page_cpu_to_dev(page, 0, PAGE_SIZE << order,
82				      DMA_BIDIRECTIONAL);
83	}
84	if (!page)
85		return 0;
86
87	if (split_pages)
88		split_page(page, order);
89	return page;
90}
91
92static void free_buffer_page(struct ion_system_heap *heap,
93			     struct ion_buffer *buffer, struct page *page,
94			     unsigned int order)
95{
96	bool cached = ion_buffer_cached(buffer);
97	bool split_pages = ion_buffer_fault_user_mappings(buffer);
98	int i;
99
100	if (!cached) {
101		struct ion_page_pool *pool = heap->pools[order_to_index(order)];
102		/* zero the pages before returning them to the pool for
103		   security.  This uses vmap as we want to set the pgprot so
104		   the writes to occur to noncached mappings, as the pool's
105		   purpose is to keep the pages out of the cache */
106		for (i = 0; i < order / PAGE_SIZE; i++) {
107			struct page *sub_page = page + i;
108			void *addr = vmap(&sub_page, 1, VM_MAP,
109					  pgprot_writecombine(PAGE_KERNEL));
110			memset(addr, 0, PAGE_SIZE);
111			vunmap(addr);
112		}
113		ion_page_pool_free(pool, page);
114	} else if (split_pages) {
115		for (i = 0; i < (1 << order); i++)
116			__free_page(page + i);
117	} else {
118		__free_pages(page, order);
119	}
120}
121
122
123static struct page_info *alloc_largest_available(struct ion_system_heap *heap,
124						 struct ion_buffer *buffer,
125						 unsigned long size,
126						 unsigned int max_order)
127{
128	struct page *page;
129	struct page_info *info;
130	int i;
131
132	for (i = 0; i < num_orders; i++) {
133		if (size < order_to_size(orders[i]))
134			continue;
135		if (max_order < orders[i])
136			continue;
137
138		page = alloc_buffer_page(heap, buffer, orders[i]);
139		if (!page)
140			continue;
141
142		info = kmalloc(sizeof(struct page_info), GFP_KERNEL);
143		info->page = page;
144		info->order = orders[i];
145		return info;
146	}
147	return NULL;
148}
149
150static int ion_system_heap_allocate(struct ion_heap *heap,
151				     struct ion_buffer *buffer,
152				     unsigned long size, unsigned long align,
153				     unsigned long flags)
154{
155	struct ion_system_heap *sys_heap = container_of(heap,
156							struct ion_system_heap,
157							heap);
158	struct sg_table *table;
159	struct scatterlist *sg;
160	int ret;
161	struct list_head pages;
162	struct page_info *info, *tmp_info;
163	int i = 0;
164	long size_remaining = PAGE_ALIGN(size);
165	unsigned int max_order = orders[0];
166	bool split_pages = ion_buffer_fault_user_mappings(buffer);
167
168	INIT_LIST_HEAD(&pages);
169	while (size_remaining > 0) {
170		info = alloc_largest_available(sys_heap, buffer, size_remaining, max_order);
171		if (!info)
172			goto err;
173		list_add_tail(&info->list, &pages);
174		size_remaining -= (1 << info->order) * PAGE_SIZE;
175		max_order = info->order;
176		i++;
177	}
178
179	table = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
180	if (!table)
181		goto err;
182
183	if (split_pages)
184		ret = sg_alloc_table(table, PAGE_ALIGN(size) / PAGE_SIZE,
185				     GFP_KERNEL);
186	else
187		ret = sg_alloc_table(table, i, GFP_KERNEL);
188
189	if (ret)
190		goto err1;
191
192	sg = table->sgl;
193	list_for_each_entry_safe(info, tmp_info, &pages, list) {
194		struct page *page = info->page;
195		if (split_pages) {
196			for (i = 0; i < (1 << info->order); i++) {
197				sg_set_page(sg, page + i, PAGE_SIZE, 0);
198				sg = sg_next(sg);
199			}
200		} else {
201			sg_set_page(sg, page, (1 << info->order) * PAGE_SIZE,
202				    0);
203			sg = sg_next(sg);
204		}
205		list_del(&info->list);
206		kfree(info);
207	}
208
209	buffer->priv_virt = table;
210	return 0;
211err1:
212	kfree(table);
213err:
214	list_for_each_entry(info, &pages, list) {
215		free_buffer_page(sys_heap, buffer, info->page, info->order);
216		kfree(info);
217	}
218	return -ENOMEM;
219}
220
221void ion_system_heap_free(struct ion_buffer *buffer)
222{
223	struct ion_heap *heap = buffer->heap;
224	struct ion_system_heap *sys_heap = container_of(heap,
225							struct ion_system_heap,
226							heap);
227	struct sg_table *table = buffer->priv_virt;
228	struct scatterlist *sg;
229	LIST_HEAD(pages);
230	int i;
231
232	for_each_sg(table->sgl, sg, table->nents, i)
233		free_buffer_page(sys_heap, buffer, sg_page(sg), get_order(sg_dma_len(sg)));
234	sg_free_table(table);
235	kfree(table);
236}
237
238struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap,
239					 struct ion_buffer *buffer)
240{
241	return buffer->priv_virt;
242}
243
244void ion_system_heap_unmap_dma(struct ion_heap *heap,
245			       struct ion_buffer *buffer)
246{
247	return;
248}
249
250void *ion_system_heap_map_kernel(struct ion_heap *heap,
251				 struct ion_buffer *buffer)
252{
253	struct scatterlist *sg;
254	int i, j;
255	void *vaddr;
256	pgprot_t pgprot;
257	struct sg_table *table = buffer->priv_virt;
258	int npages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
259	struct page **pages = vmalloc(sizeof(struct page *) * npages);
260	struct page **tmp = pages;
261
262	if (!pages)
263		return 0;
264
265	if (buffer->flags & ION_FLAG_CACHED)
266		pgprot = PAGE_KERNEL;
267	else
268		pgprot = pgprot_writecombine(PAGE_KERNEL);
269
270	for_each_sg(table->sgl, sg, table->nents, i) {
271		int npages_this_entry = PAGE_ALIGN(sg_dma_len(sg)) / PAGE_SIZE;
272		struct page *page = sg_page(sg);
273		BUG_ON(i >= npages);
274		for (j = 0; j < npages_this_entry; j++) {
275			*(tmp++) = page++;
276		}
277	}
278	vaddr = vmap(pages, npages, VM_MAP, pgprot);
279	vfree(pages);
280
281	return vaddr;
282}
283
284void ion_system_heap_unmap_kernel(struct ion_heap *heap,
285				  struct ion_buffer *buffer)
286{
287	vunmap(buffer->vaddr);
288}
289
290int ion_system_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
291			     struct vm_area_struct *vma)
292{
293	struct sg_table *table = buffer->priv_virt;
294	unsigned long addr = vma->vm_start;
295	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
296	struct scatterlist *sg;
297	int i;
298
299	for_each_sg(table->sgl, sg, table->nents, i) {
300		struct page *page = sg_page(sg);
301		unsigned long remainder = vma->vm_end - addr;
302		unsigned long len = sg_dma_len(sg);
303
304		if (offset >= sg_dma_len(sg)) {
305			offset -= sg_dma_len(sg);
306			continue;
307		} else if (offset) {
308			page += offset / PAGE_SIZE;
309			len = sg_dma_len(sg) - offset;
310			offset = 0;
311		}
312		len = min(len, remainder);
313		remap_pfn_range(vma, addr, page_to_pfn(page), len,
314				vma->vm_page_prot);
315		addr += len;
316		if (addr >= vma->vm_end)
317			return 0;
318	}
319	return 0;
320}
321
322static struct ion_heap_ops system_heap_ops = {
323	.allocate = ion_system_heap_allocate,
324	.free = ion_system_heap_free,
325	.map_dma = ion_system_heap_map_dma,
326	.unmap_dma = ion_system_heap_unmap_dma,
327	.map_kernel = ion_system_heap_map_kernel,
328	.unmap_kernel = ion_system_heap_unmap_kernel,
329	.map_user = ion_system_heap_map_user,
330};
331
332static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
333				      void *unused)
334{
335
336	struct ion_system_heap *sys_heap = container_of(heap,
337							struct ion_system_heap,
338							heap);
339	int i;
340	for (i = 0; i < num_orders; i++) {
341		struct ion_page_pool *pool = sys_heap->pools[i];
342		seq_printf(s, "%d order %u highmem pages in pool = %lu total\n",
343			   pool->high_count, pool->order,
344			   (1 << pool->order) * PAGE_SIZE * pool->high_count);
345		seq_printf(s, "%d order %u lowmem pages in pool = %lu total\n",
346			   pool->low_count, pool->order,
347			   (1 << pool->order) * PAGE_SIZE * pool->low_count);
348	}
349	return 0;
350}
351
352struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
353{
354	struct ion_system_heap *heap;
355	int i;
356
357	heap = kzalloc(sizeof(struct ion_system_heap), GFP_KERNEL);
358	if (!heap)
359		return ERR_PTR(-ENOMEM);
360	heap->heap.ops = &system_heap_ops;
361	heap->heap.type = ION_HEAP_TYPE_SYSTEM;
362	heap->pools = kzalloc(sizeof(struct ion_page_pool *) * num_orders,
363			      GFP_KERNEL);
364	if (!heap->pools)
365		goto err_alloc_pools;
366	for (i = 0; i < num_orders; i++) {
367		struct ion_page_pool *pool;
368		gfp_t gfp_flags = low_order_gfp_flags;
369
370		if (orders[i] > 4)
371			gfp_flags = high_order_gfp_flags;
372		pool = ion_page_pool_create(gfp_flags, orders[i]);
373		if (!pool)
374			goto err_create_pool;
375		heap->pools[i] = pool;
376	}
377	heap->heap.debug_show = ion_system_heap_debug_show;
378	return &heap->heap;
379err_create_pool:
380	for (i = 0; i < num_orders; i++)
381		if (heap->pools[i])
382			ion_page_pool_destroy(heap->pools[i]);
383	kfree(heap->pools);
384err_alloc_pools:
385	kfree(heap);
386	return ERR_PTR(-ENOMEM);
387}
388
389void ion_system_heap_destroy(struct ion_heap *heap)
390{
391	struct ion_system_heap *sys_heap = container_of(heap,
392							struct ion_system_heap,
393							heap);
394	int i;
395
396	for (i = 0; i < num_orders; i++)
397		ion_page_pool_destroy(sys_heap->pools[i]);
398	kfree(sys_heap->pools);
399	kfree(sys_heap);
400}
401
402static int ion_system_contig_heap_allocate(struct ion_heap *heap,
403					   struct ion_buffer *buffer,
404					   unsigned long len,
405					   unsigned long align,
406					   unsigned long flags)
407{
408	buffer->priv_virt = kzalloc(len, GFP_KERNEL);
409	if (!buffer->priv_virt)
410		return -ENOMEM;
411	return 0;
412}
413
414void ion_system_contig_heap_free(struct ion_buffer *buffer)
415{
416	kfree(buffer->priv_virt);
417}
418
419static int ion_system_contig_heap_phys(struct ion_heap *heap,
420				       struct ion_buffer *buffer,
421				       ion_phys_addr_t *addr, size_t *len)
422{
423	*addr = virt_to_phys(buffer->priv_virt);
424	*len = buffer->size;
425	return 0;
426}
427
428struct sg_table *ion_system_contig_heap_map_dma(struct ion_heap *heap,
429						struct ion_buffer *buffer)
430{
431	struct sg_table *table;
432	int ret;
433
434	table = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
435	if (!table)
436		return ERR_PTR(-ENOMEM);
437	ret = sg_alloc_table(table, 1, GFP_KERNEL);
438	if (ret) {
439		kfree(table);
440		return ERR_PTR(ret);
441	}
442	sg_set_page(table->sgl, virt_to_page(buffer->priv_virt), buffer->size,
443		    0);
444	return table;
445}
446
447void ion_system_contig_heap_unmap_dma(struct ion_heap *heap,
448				      struct ion_buffer *buffer)
449{
450	sg_free_table(buffer->sg_table);
451	kfree(buffer->sg_table);
452}
453
454int ion_system_contig_heap_map_user(struct ion_heap *heap,
455				    struct ion_buffer *buffer,
456				    struct vm_area_struct *vma)
457{
458	unsigned long pfn = __phys_to_pfn(virt_to_phys(buffer->priv_virt));
459	return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
460			       vma->vm_end - vma->vm_start,
461			       vma->vm_page_prot);
462
463}
464
465static struct ion_heap_ops kmalloc_ops = {
466	.allocate = ion_system_contig_heap_allocate,
467	.free = ion_system_contig_heap_free,
468	.phys = ion_system_contig_heap_phys,
469	.map_dma = ion_system_contig_heap_map_dma,
470	.unmap_dma = ion_system_contig_heap_unmap_dma,
471	.map_kernel = ion_system_heap_map_kernel,
472	.unmap_kernel = ion_system_heap_unmap_kernel,
473	.map_user = ion_system_contig_heap_map_user,
474};
475
476struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
477{
478	struct ion_heap *heap;
479
480	heap = kzalloc(sizeof(struct ion_heap), GFP_KERNEL);
481	if (!heap)
482		return ERR_PTR(-ENOMEM);
483	heap->ops = &kmalloc_ops;
484	heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
485	return heap;
486}
487
488void ion_system_contig_heap_destroy(struct ion_heap *heap)
489{
490	kfree(heap);
491}
492
493