summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/staging/android/ion
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/staging/android/ion')
-rw-r--r--kernel/drivers/staging/android/ion/compat_ion.h1
-rw-r--r--kernel/drivers/staging/android/ion/ion.c82
-rw-r--r--kernel/drivers/staging/android/ion/ion.h10
-rw-r--r--kernel/drivers/staging/android/ion/ion_chunk_heap.c4
-rw-r--r--kernel/drivers/staging/android/ion/ion_cma_heap.c10
-rw-r--r--kernel/drivers/staging/android/ion/ion_heap.c4
-rw-r--r--kernel/drivers/staging/android/ion/ion_page_pool.c15
-rw-r--r--kernel/drivers/staging/android/ion/ion_priv.h9
-rw-r--r--kernel/drivers/staging/android/ion/ion_system_heap.c25
-rw-r--r--kernel/drivers/staging/android/ion/ion_test.c21
-rw-r--r--kernel/drivers/staging/android/ion/tegra/Makefile2
-rw-r--r--kernel/drivers/staging/android/ion/tegra/tegra_ion.c1
12 files changed, 111 insertions, 73 deletions
diff --git a/kernel/drivers/staging/android/ion/compat_ion.h b/kernel/drivers/staging/android/ion/compat_ion.h
index c2ad5893d..9da8f9176 100644
--- a/kernel/drivers/staging/android/ion/compat_ion.h
+++ b/kernel/drivers/staging/android/ion/compat_ion.h
@@ -1,5 +1,4 @@
/*
-
* drivers/staging/android/ion/compat_ion.h
*
* Copyright (C) 2013 Google, Inc.
diff --git a/kernel/drivers/staging/android/ion/ion.c b/kernel/drivers/staging/android/ion/ion.c
index b0b96ab31..e237e9f33 100644
--- a/kernel/drivers/staging/android/ion/ion.c
+++ b/kernel/drivers/staging/android/ion/ion.c
@@ -1,5 +1,5 @@
/*
-
+ *
* drivers/staging/android/ion/ion.c
*
* Copyright (C) 2011 Google, Inc.
@@ -213,10 +213,10 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
"heap->ops->map_dma should return ERR_PTR on error"))
table = ERR_PTR(-EINVAL);
if (IS_ERR(table)) {
- heap->ops->free(buffer);
- kfree(buffer);
- return ERR_CAST(table);
+ ret = -EINVAL;
+ goto err1;
}
+
buffer->sg_table = table;
if (ion_buffer_fault_user_mappings(buffer)) {
int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
@@ -226,7 +226,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->pages = vmalloc(sizeof(struct page *) * num_pages);
if (!buffer->pages) {
ret = -ENOMEM;
- goto err1;
+ goto err;
}
for_each_sg(table->sgl, sg, table->nents, i) {
@@ -235,23 +235,22 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
for (j = 0; j < sg->length / PAGE_SIZE; j++)
buffer->pages[k++] = page++;
}
-
- if (ret)
- goto err;
}
buffer->dev = dev;
buffer->size = len;
INIT_LIST_HEAD(&buffer->vmas);
mutex_init(&buffer->lock);
- /* this will set up dma addresses for the sglist -- it is not
- technically correct as per the dma api -- a specific
- device isn't really taking ownership here. However, in practice on
- our systems the only dma_address space is physical addresses.
- Additionally, we can't afford the overhead of invalidating every
- allocation via dma_map_sg. The implicit contract here is that
- memory coming from the heaps is ready for dma, ie if it has a
- cached mapping that mapping has been invalidated */
+ /*
+ * this will set up dma addresses for the sglist -- it is not
+ * technically correct as per the dma api -- a specific
+ * device isn't really taking ownership here. However, in practice on
+ * our systems the only dma_address space is physical addresses.
+ * Additionally, we can't afford the overhead of invalidating every
+ * allocation via dma_map_sg. The implicit contract here is that
+ * memory coming from the heaps is ready for dma, ie if it has a
+ * cached mapping that mapping has been invalidated
+ */
for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i)
sg_dma_address(sg) = sg_phys(sg);
mutex_lock(&dev->buffer_lock);
@@ -261,9 +260,8 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
err:
heap->ops->unmap_dma(heap, buffer);
- heap->ops->free(buffer);
err1:
- vfree(buffer->pages);
+ heap->ops->free(buffer);
err2:
kfree(buffer);
return ERR_PTR(ret);
@@ -753,8 +751,10 @@ struct ion_client *ion_client_create(struct ion_device *dev,
get_task_struct(current->group_leader);
task_lock(current->group_leader);
pid = task_pid_nr(current->group_leader);
- /* don't bother to store task struct for kernel threads,
- they can't be killed anyway */
+ /*
+ * don't bother to store task struct for kernel threads,
+ * they can't be killed anyway
+ */
if (current->group_leader->flags & PF_KTHREAD) {
put_task_struct(current->group_leader);
task = NULL;
@@ -997,7 +997,7 @@ static void ion_vm_close(struct vm_area_struct *vma)
mutex_unlock(&buffer->lock);
}
-static struct vm_operations_struct ion_vma_ops = {
+static const struct vm_operations_struct ion_vma_ops = {
.open = ion_vm_open,
.close = ion_vm_close,
.fault = ion_vm_fault,
@@ -1103,10 +1103,10 @@ static struct dma_buf_ops dma_buf_ops = {
struct dma_buf *ion_share_dma_buf(struct ion_client *client,
struct ion_handle *handle)
{
+ DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
struct ion_buffer *buffer;
struct dma_buf *dmabuf;
bool valid_handle;
- DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
mutex_lock(&client->lock);
valid_handle = ion_handle_validate(client, handle);
@@ -1179,13 +1179,13 @@ struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd)
mutex_unlock(&client->lock);
goto end;
}
- mutex_unlock(&client->lock);
handle = ion_handle_create(client, buffer);
- if (IS_ERR(handle))
+ if (IS_ERR(handle)) {
+ mutex_unlock(&client->lock);
goto end;
+ }
- mutex_lock(&client->lock);
ret = ion_handle_add(client, handle);
mutex_unlock(&client->lock);
if (ret) {
@@ -1466,7 +1466,6 @@ static const struct file_operations debug_heap_fops = {
.release = single_release,
};
-#ifdef DEBUG_HEAP_SHRINKER
static int debug_shrink_set(void *data, u64 val)
{
struct ion_heap *heap = data;
@@ -1474,15 +1473,14 @@ static int debug_shrink_set(void *data, u64 val)
int objs;
sc.gfp_mask = -1;
- sc.nr_to_scan = 0;
-
- if (!val)
- return 0;
+ sc.nr_to_scan = val;
- objs = heap->shrinker.shrink(&heap->shrinker, &sc);
- sc.nr_to_scan = objs;
+ if (!val) {
+ objs = heap->shrinker.count_objects(&heap->shrinker, &sc);
+ sc.nr_to_scan = objs;
+ }
- heap->shrinker.shrink(&heap->shrinker, &sc);
+ heap->shrinker.scan_objects(&heap->shrinker, &sc);
return 0;
}
@@ -1495,14 +1493,13 @@ static int debug_shrink_get(void *data, u64 *val)
sc.gfp_mask = -1;
sc.nr_to_scan = 0;
- objs = heap->shrinker.shrink(&heap->shrinker, &sc);
+ objs = heap->shrinker.count_objects(&heap->shrinker, &sc);
*val = objs;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
debug_shrink_set, "%llu\n");
-#endif
void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
{
@@ -1524,8 +1521,10 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
heap->dev = dev;
down_write(&dev->lock);
- /* use negative heap->id to reverse the priority -- when traversing
- the list later attempt higher id numbers first */
+ /*
+ * use negative heap->id to reverse the priority -- when traversing
+ * the list later attempt higher id numbers first
+ */
plist_node_init(&heap->node, -heap->id);
plist_add(&heap->node, &dev->heaps);
debug_file = debugfs_create_file(heap->name, 0664,
@@ -1540,8 +1539,7 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
path, heap->name);
}
-#ifdef DEBUG_HEAP_SHRINKER
- if (heap->shrinker.shrink) {
+ if (heap->shrinker.count_objects && heap->shrinker.scan_objects) {
char debug_name[64];
snprintf(debug_name, 64, "%s_shrink", heap->name);
@@ -1556,9 +1554,10 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
path, debug_name);
}
}
-#endif
+
up_write(&dev->lock);
}
+EXPORT_SYMBOL(ion_device_add_heap);
struct ion_device *ion_device_create(long (*custom_ioctl)
(struct ion_client *client,
@@ -1579,6 +1578,7 @@ struct ion_device *ion_device_create(long (*custom_ioctl)
ret = misc_register(&idev->dev);
if (ret) {
pr_err("ion: failed to register misc device.\n");
+ kfree(idev);
return ERR_PTR(ret);
}
@@ -1607,6 +1607,7 @@ debugfs_done:
idev->clients = RB_ROOT;
return idev;
}
+EXPORT_SYMBOL(ion_device_create);
void ion_device_destroy(struct ion_device *dev)
{
@@ -1615,6 +1616,7 @@ void ion_device_destroy(struct ion_device *dev)
/* XXX need to free the heaps and clients ? */
kfree(dev);
}
+EXPORT_SYMBOL(ion_device_destroy);
void __init ion_reserve(struct ion_platform_data *data)
{
diff --git a/kernel/drivers/staging/android/ion/ion.h b/kernel/drivers/staging/android/ion/ion.h
index 443db8459..b860c5f57 100644
--- a/kernel/drivers/staging/android/ion/ion.h
+++ b/kernel/drivers/staging/android/ion/ion.h
@@ -28,10 +28,12 @@ struct ion_mapper;
struct ion_client;
struct ion_buffer;
-/* This should be removed some day when phys_addr_t's are fully
- plumbed in the kernel, and all instances of ion_phys_addr_t should
- be converted to phys_addr_t. For the time being many kernel interfaces
- do not accept phys_addr_t's that would have to */
+/*
+ * This should be removed some day when phys_addr_t's are fully
+ * plumbed in the kernel, and all instances of ion_phys_addr_t should
+ * be converted to phys_addr_t. For the time being many kernel interfaces
+ * do not accept phys_addr_t's that would have to
+ */
#define ion_phys_addr_t unsigned long
/**
diff --git a/kernel/drivers/staging/android/ion/ion_chunk_heap.c b/kernel/drivers/staging/android/ion/ion_chunk_heap.c
index 3e6ec2ee6..0813163f9 100644
--- a/kernel/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/kernel/drivers/staging/android/ion/ion_chunk_heap.c
@@ -173,8 +173,8 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
chunk_heap->heap.ops = &chunk_heap_ops;
chunk_heap->heap.type = ION_HEAP_TYPE_CHUNK;
chunk_heap->heap.flags = ION_HEAP_FLAG_DEFER_FREE;
- pr_info("%s: base %lu size %zu align %ld\n", __func__, chunk_heap->base,
- heap_data->size, heap_data->align);
+ pr_debug("%s: base %lu size %zu align %ld\n", __func__,
+ chunk_heap->base, heap_data->size, heap_data->align);
return &chunk_heap->heap;
diff --git a/kernel/drivers/staging/android/ion/ion_cma_heap.c b/kernel/drivers/staging/android/ion/ion_cma_heap.c
index f4211f1be..a3446da4f 100644
--- a/kernel/drivers/staging/android/ion/ion_cma_heap.c
+++ b/kernel/drivers/staging/android/ion/ion_cma_heap.c
@@ -73,8 +73,8 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
if (!info->table)
goto free_mem;
- if (dma_common_get_sgtable
- (dev, info->table, info->cpu_addr, info->handle, len))
+ if (dma_get_sgtable(dev, info->table, info->cpu_addr, info->handle,
+ len))
goto free_table;
/* keep this for memory release */
buffer->priv_virt = info;
@@ -180,8 +180,10 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
return ERR_PTR(-ENOMEM);
cma_heap->heap.ops = &ion_cma_ops;
- /* get device from private heaps data, later it will be
- * used to make the link with reserved CMA memory */
+ /*
+ * get device from private heaps data, later it will be
+ * used to make the link with reserved CMA memory
+ */
cma_heap->dev = data->priv;
cma_heap->heap.type = ION_HEAP_TYPE_DMA;
return &cma_heap->heap;
diff --git a/kernel/drivers/staging/android/ion/ion_heap.c b/kernel/drivers/staging/android/ion/ion_heap.c
index fd13d05b5..ca15a87f6 100644
--- a/kernel/drivers/staging/android/ion/ion_heap.c
+++ b/kernel/drivers/staging/android/ion/ion_heap.c
@@ -56,7 +56,7 @@ void *ion_heap_map_kernel(struct ion_heap *heap,
vaddr = vmap(pages, npages, VM_MAP, pgprot);
vfree(pages);
- if (vaddr == NULL)
+ if (!vaddr)
return ERR_PTR(-ENOMEM);
return vaddr;
@@ -352,6 +352,7 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
heap->id = heap_data->id;
return heap;
}
+EXPORT_SYMBOL(ion_heap_create);
void ion_heap_destroy(struct ion_heap *heap)
{
@@ -379,3 +380,4 @@ void ion_heap_destroy(struct ion_heap *heap)
heap->type);
}
}
+EXPORT_SYMBOL(ion_heap_destroy);
diff --git a/kernel/drivers/staging/android/ion/ion_page_pool.c b/kernel/drivers/staging/android/ion/ion_page_pool.c
index 4b88f11e5..fd7e23e0c 100644
--- a/kernel/drivers/staging/android/ion/ion_page_pool.c
+++ b/kernel/drivers/staging/android/ion/ion_page_pool.c
@@ -19,7 +19,7 @@
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/list.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/slab.h>
#include <linux/swap.h>
#include "ion_priv.h"
@@ -116,7 +116,7 @@ static int ion_page_pool_total(struct ion_page_pool *pool, bool high)
int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
int nr_to_scan)
{
- int freed;
+ int freed = 0;
bool high;
if (current_is_kswapd())
@@ -127,7 +127,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
if (nr_to_scan == 0)
return ion_page_pool_total(pool, high);
- for (freed = 0; freed < nr_to_scan; freed++) {
+ while (freed < nr_to_scan) {
struct page *page;
mutex_lock(&pool->mutex);
@@ -141,6 +141,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
}
mutex_unlock(&pool->mutex);
ion_page_pool_free_pages(pool, page);
+ freed += (1 << pool->order);
}
return freed;
@@ -173,10 +174,4 @@ static int __init ion_page_pool_init(void)
{
return 0;
}
-
-static void __exit ion_page_pool_exit(void)
-{
-}
-
-module_init(ion_page_pool_init);
-module_exit(ion_page_pool_exit);
+device_initcall(ion_page_pool_init);
diff --git a/kernel/drivers/staging/android/ion/ion_priv.h b/kernel/drivers/staging/android/ion/ion_priv.h
index 18a5f93e1..0239883bf 100644
--- a/kernel/drivers/staging/android/ion/ion_priv.h
+++ b/kernel/drivers/staging/android/ion/ion_priv.h
@@ -33,7 +33,7 @@ struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
/**
* struct ion_buffer - metadata for a particular buffer
- * @ref: refernce count
+ * @ref: reference count
* @node: node in the ion_device buffers tree
* @dev: back pointer to the ion_device
* @heap: back pointer to the heap the buffer came from
@@ -46,7 +46,7 @@ struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
* an ion_phys_addr_t (and someday a phys_addr_t)
* @lock: protects the buffers cnt fields
* @kmap_cnt: number of times the buffer is mapped to the kernel
- * @vaddr: the kenrel mapping if kmap_cnt is not zero
+ * @vaddr: the kernel mapping if kmap_cnt is not zero
* @dmap_cnt: number of times the buffer is mapped for dma
* @sg_table: the sg table for the buffer if dmap_cnt is not zero
* @pages: flat array of pages in the buffer -- used by fault
@@ -266,7 +266,7 @@ void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer);
/**
* ion_heap_freelist_drain - drain the deferred free list
* @heap: the heap
- * @size: ammount of memory to drain in bytes
+ * @size: amount of memory to drain in bytes
*
* Drains the indicated amount of memory from the deferred freelist immediately.
* Returns the total amount freed. The total freed may be higher depending
@@ -346,7 +346,8 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
* to keep a pool of pre allocated memory to use from your heap. Keeping
* a pool of memory that is ready for dma, ie any cached mapping have been
* invalidated from the cache, provides a significant performance benefit on
- * many systems */
+ * many systems
+ */
/**
* struct ion_page_pool - pagepool struct
diff --git a/kernel/drivers/staging/android/ion/ion_system_heap.c b/kernel/drivers/staging/android/ion/ion_system_heap.c
index da2a63c0a..d4c3e5512 100644
--- a/kernel/drivers/staging/android/ion/ion_system_heap.c
+++ b/kernel/drivers/staging/android/ion/ion_system_heap.c
@@ -27,7 +27,7 @@
#include "ion_priv.h"
static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN |
- __GFP_NORETRY) & ~__GFP_WAIT;
+ __GFP_NORETRY) & ~__GFP_DIRECT_RECLAIM;
static gfp_t low_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN);
static const unsigned int orders[] = {8, 4, 0};
static const int num_orders = ARRAY_SIZE(orders);
@@ -185,8 +185,11 @@ static void ion_system_heap_free(struct ion_buffer *buffer)
struct scatterlist *sg;
int i;
- /* uncached pages come from the page pools, zero them before returning
- for security purposes (other allocations are zerod at alloc time */
+ /*
+ * uncached pages come from the page pools, zero them before returning
+ * for security purposes (other allocations are zerod at
+ * alloc time
+ */
if (!cached && !(buffer->private_flags & ION_PRIV_FLAG_SHRINKER_FREE))
ion_heap_buffer_zero(buffer);
@@ -212,14 +215,26 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask,
{
struct ion_system_heap *sys_heap;
int nr_total = 0;
- int i;
+ int i, nr_freed;
+ int only_scan = 0;
sys_heap = container_of(heap, struct ion_system_heap, heap);
+ if (!nr_to_scan)
+ only_scan = 1;
+
for (i = 0; i < num_orders; i++) {
struct ion_page_pool *pool = sys_heap->pools[i];
- nr_total += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
+ nr_freed = ion_page_pool_shrink(pool, gfp_mask, nr_to_scan);
+ nr_total += nr_freed;
+
+ if (!only_scan) {
+ nr_to_scan -= nr_freed;
+ /* shrink completed */
+ if (nr_to_scan <= 0)
+ break;
+ }
}
return nr_total;
diff --git a/kernel/drivers/staging/android/ion/ion_test.c b/kernel/drivers/staging/android/ion/ion_test.c
index 3bc461cbb..b8dcf5a26 100644
--- a/kernel/drivers/staging/android/ion/ion_test.c
+++ b/kernel/drivers/staging/android/ion/ion_test.c
@@ -261,7 +261,21 @@ static int __init ion_test_probe(struct platform_device *pdev)
return 0;
}
+static int ion_test_remove(struct platform_device *pdev)
+{
+ struct ion_test_device *testdev;
+
+ testdev = platform_get_drvdata(pdev);
+ if (!testdev)
+ return -ENODATA;
+
+ misc_deregister(&testdev->misc);
+ return 0;
+}
+
+static struct platform_device *ion_test_pdev;
static struct platform_driver ion_test_platform_driver = {
+ .remove = ion_test_remove,
.driver = {
.name = "ion-test",
},
@@ -269,13 +283,18 @@ static struct platform_driver ion_test_platform_driver = {
static int __init ion_test_init(void)
{
- platform_device_register_simple("ion-test", -1, NULL, 0);
+ ion_test_pdev = platform_device_register_simple("ion-test",
+ -1, NULL, 0);
+ if (!ion_test_pdev)
+ return -ENODEV;
+
return platform_driver_probe(&ion_test_platform_driver, ion_test_probe);
}
static void __exit ion_test_exit(void)
{
platform_driver_unregister(&ion_test_platform_driver);
+ platform_device_unregister(ion_test_pdev);
}
module_init(ion_test_init);
diff --git a/kernel/drivers/staging/android/ion/tegra/Makefile b/kernel/drivers/staging/android/ion/tegra/Makefile
index 11cd003fb..808f1f53f 100644
--- a/kernel/drivers/staging/android/ion/tegra/Makefile
+++ b/kernel/drivers/staging/android/ion/tegra/Makefile
@@ -1 +1 @@
-obj-y += tegra_ion.o
+obj-$(CONFIG_ION_TEGRA) += tegra_ion.o
diff --git a/kernel/drivers/staging/android/ion/tegra/tegra_ion.c b/kernel/drivers/staging/android/ion/tegra/tegra_ion.c
index 5b8ef0e66..4d3c516cc 100644
--- a/kernel/drivers/staging/android/ion/tegra/tegra_ion.c
+++ b/kernel/drivers/staging/android/ion/tegra/tegra_ion.c
@@ -15,6 +15,7 @@
*/
#include <linux/err.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "../ion.h"