Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1603700 > unrolled thread
| Started by | Laura Abbott <labbott@redhat.com> |
|---|---|
| First post | 2017-03-18 02:20 +0100 |
| Last post | 2017-03-18 15:50 +0100 |
| Articles | 13 — 1 participant |
Back to article view | Back to linux.kernel
[RFC PATCHv2 00/21] Ion clean in preparation for moving out of staging Laura Abbott <labbott@redhat.com> - 2017-03-18 02:20 +0100
[RFC PATCHv2 18/21] staging: android: ion: Rework heap registration/enumeration Laura Abbott <labbott@redhat.com> - 2017-03-18 02:30 +0100
[RFC PATCHv2 14/21] staging: android: ion: Stop butchering the DMA address Laura Abbott <labbott@redhat.com> - 2017-03-18 02:30 +0100
[RFC PATCHv2 02/21] cma: Introduce cma_for_each_area Laura Abbott <labbott@redhat.com> - 2017-03-18 02:50 +0100
[RFC PATCHv2 11/21] staging: android: ion: Remove duplicate ION_IOC_MAP Laura Abbott <labbott@redhat.com> - 2017-03-18 03:10 +0100
[RFC PATCHv2 20/21] staging: android: ion: Remove ion_handle and ion_client Laura Abbott <labbott@redhat.com> - 2017-03-18 03:10 +0100
[RFC PATCHv2 07/21] staging: android: ion: Remove page faulting support Laura Abbott <labbott@redhat.com> - 2017-03-18 03:50 +0100
[RFC PATCHv2 10/21] staging: android: ion: Remove import interface Laura Abbott <labbott@redhat.com> - 2017-03-18 04:00 +0100
[RFC PATCHv2 03/21] staging: android: ion: Remove dmap_cnt Laura Abbott <labbott@redhat.com> - 2017-03-18 04:00 +0100
[RFC PATCHv2 15/21] staging: android: ion: Break the ABI in the name of forward progress Laura Abbott <labbott@redhat.com> - 2017-03-18 04:10 +0100
[RFC PATCHv2 21/21] staging: android: ion: Set query return value Laura Abbott <labbott@redhat.com> - 2017-03-18 04:40 +0100
[RFC PATCHv2 04/21] staging: android: ion: Remove alignment from allocation field Laura Abbott <labbott@redhat.com> - 2017-03-18 05:00 +0100
[RFC PATCHv2 06/21] staging: android: ion: Call dma_map_sg for syncing and mapping Laura Abbott <labbott@redhat.com> - 2017-03-18 15:50 +0100
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 02:20 +0100 |
| Subject | [RFC PATCHv2 00/21] Ion clean in preparation for moving out of staging |
| Message-ID | <tmb2y-6Yb-3@gated-at.bofh.it> |
Hi, This is v2 of the series to do some serious Ion clean up in preparation for moving out of staging. I got good feedback last time so this series mostly attempts to address that feedback and do more still more cleanup. Highlights: - All calls to DMA APIs should now be with a real actual proper device structure - Patch to stop setting sg_dma_address manually now included - Fix for a bug in the query interface - Removal of custom ioctl interface - Removal of import interface - Removal of any notion of using Ion as an in kernel interface. - Cleanup of ABI so compat interface is no longer needed - Deletion of a bit more platform code - Combined heap enumeration and heap registration code up so there are fewer layers of abstraction - Some general cleanup and header reduction. - Removal of both the ion_client and ion_handle structures since these mostly become redundant. As a result, Ion only returns a dma_buf fd. The overall result is that the only Ion interfaces are the query ioctl and the alloc ioctl. The following are still TODOs/open problems: - Sumit's comments about the CMA naming. - Bindings/platform for chunk and carveout heap - There was some discussion about making the sg_table duplication generic. I got bogged down in handling some of the edge cases for generic handling so I put this aside. Making it generic is still something that should happen. - More fine-grained support for restricting heap access. There are good arguments to be made for having a way for having good integration with selinux and other policy mechanisms. - While not on the original list, there is still no good good test standalone test framework. I noticed that the existing ion_test was fairly generic so I proposed moving it to dma_buf. Daniel Vetter suggested just using the VGEM module instead. Ideally, the tests can live as part of some other existing test set (drm tests maybe?) Feedback appreciated as always. Thanks, Laura Laura Abbott (21): cma: Store a name in the cma structure cma: Introduce cma_for_each_area staging: android: ion: Remove dmap_cnt staging: android: ion: Remove alignment from allocation field staging: android: ion: Duplicate sg_table staging: android: ion: Call dma_map_sg for syncing and mapping staging: android: ion: Remove page faulting support staging: android: ion: Remove crufty cache support staging: android: ion: Remove custom ioctl interface staging: android: ion: Remove import interface staging: android: ion: Remove duplicate ION_IOC_MAP staging: android: ion: Remove old platform support staging: android: ion: Use CMA APIs directly staging: android: ion: Stop butchering the DMA address staging: android: ion: Break the ABI in the name of forward progress staging: android: ion: Get rid of ion_phys_addr_t staging: android: ion: Collapse internal header files staging: android: ion: Rework heap registration/enumeration staging: android: ion: Drop ion_map_kernel interface staging: android: ion: Remove ion_handle and ion_client staging: android: ion: Set query return value drivers/base/dma-contiguous.c | 5 +- drivers/staging/android/ion/Kconfig | 56 +- drivers/staging/android/ion/Makefile | 18 +- drivers/staging/android/ion/compat_ion.c | 195 ---- drivers/staging/android/ion/compat_ion.h | 29 - drivers/staging/android/ion/hisilicon/Kconfig | 5 - drivers/staging/android/ion/hisilicon/Makefile | 1 - drivers/staging/android/ion/hisilicon/hi6220_ion.c | 113 -- drivers/staging/android/ion/ion-ioctl.c | 85 +- drivers/staging/android/ion/ion.c | 1164 +++----------------- drivers/staging/android/ion/ion.h | 393 +++++-- drivers/staging/android/ion/ion_carveout_heap.c | 37 +- drivers/staging/android/ion/ion_chunk_heap.c | 27 +- drivers/staging/android/ion/ion_cma_heap.c | 125 +-- drivers/staging/android/ion/ion_dummy_driver.c | 156 --- drivers/staging/android/ion/ion_heap.c | 68 -- drivers/staging/android/ion/ion_of.c | 184 ---- drivers/staging/android/ion/ion_of.h | 37 - drivers/staging/android/ion/ion_page_pool.c | 6 +- drivers/staging/android/ion/ion_priv.h | 473 -------- drivers/staging/android/ion/ion_system_heap.c | 53 +- drivers/staging/android/ion/ion_test.c | 305 ----- drivers/staging/android/ion/tegra/Makefile | 1 - drivers/staging/android/ion/tegra/tegra_ion.c | 80 -- drivers/staging/android/uapi/ion.h | 86 +- drivers/staging/android/uapi/ion_test.h | 69 -- include/linux/cma.h | 6 +- mm/cma.c | 25 +- mm/cma.h | 1 + mm/cma_debug.c | 2 +- 30 files changed, 610 insertions(+), 3195 deletions(-) delete mode 100644 drivers/staging/android/ion/compat_ion.c delete mode 100644 drivers/staging/android/ion/compat_ion.h delete mode 100644 drivers/staging/android/ion/hisilicon/Kconfig delete mode 100644 drivers/staging/android/ion/hisilicon/Makefile delete mode 100644 drivers/staging/android/ion/hisilicon/hi6220_ion.c delete mode 100644 drivers/staging/android/ion/ion_dummy_driver.c delete mode 100644 drivers/staging/android/ion/ion_of.c delete mode 100644 drivers/staging/android/ion/ion_of.h delete mode 100644 drivers/staging/android/ion/ion_priv.h delete mode 100644 drivers/staging/android/ion/ion_test.c delete mode 100644 drivers/staging/android/ion/tegra/Makefile delete mode 100644 drivers/staging/android/ion/tegra/tegra_ion.c delete mode 100644 drivers/staging/android/uapi/ion_test.h -- 2.7.4
[toc] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 02:30 +0100 |
| Subject | [RFC PATCHv2 18/21] staging: android: ion: Rework heap registration/enumeration |
| Message-ID | <tmblT-77o-1@gated-at.bofh.it> |
| In reply to | #1603700 |
The current model of Ion heap registration is based on the outdated
model of board files. The replacement for board files (devicetree)
isn't a good replacement for what Ion wants to do. In actuality, Ion
wants to show what memory is available in the system for something else
to figure out what to use. Switch to a model where Ion creates its
device unconditionally and heaps are registed as available regions.
Currently, only system and CMA heaps are converted over to the new
model. Carveout and chunk heaps can be converted over when someone wants
to figure out how.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/Kconfig | 25 +++++++++
drivers/staging/android/ion/Makefile | 7 +--
drivers/staging/android/ion/ion.c | 28 +++++------
drivers/staging/android/ion/ion.h | 40 +--------------
drivers/staging/android/ion/ion_carveout_heap.c | 10 ----
drivers/staging/android/ion/ion_chunk_heap.c | 9 ----
drivers/staging/android/ion/ion_cma_heap.c | 24 +++++++--
drivers/staging/android/ion/ion_heap.c | 67 -------------------------
drivers/staging/android/ion/ion_system_heap.c | 38 ++++++++------
9 files changed, 85 insertions(+), 163 deletions(-)
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
index 15108c4..a517b2d 100644
--- a/drivers/staging/android/ion/Kconfig
+++ b/drivers/staging/android/ion/Kconfig
@@ -10,6 +10,31 @@ menuconfig ION
If you're not using Android its probably safe to
say N here.
+config ION_SYSTEM_HEAP
+ bool "Ion system heap"
+ depends on ION
+ help
+ Choose this option to enable the Ion system heap. The system heap
+ is backed by pages from the buddy allocator. If in doubt, say Y.
+
+config ION_CARVEOUT_HEAP
+ bool "Ion carveout heap support"
+ depends on ION
+ help
+ Choose this option to enable carveout heaps with Ion. Carveout heaps
+ are backed by memory reserved from the system. Allocation times are
+ typically faster at the cost of memory not being used. Unless you
+ know your system has these regions, you should say N here.
+
+config ION_CHUNK_HEAP
+ bool "Ion chunk heap support"
+ depends on ION
+ help
+ Choose this option to enable chunk heaps with Ion. This heap is
+ similar in function the carveout heap but memory is broken down
+ into smaller chunk sizes, typically corresponding to a TLB size.
+ Unless you know your system has these regions, you should say N here.
+
config ION_CMA_HEAP
bool "Ion CMA heap support"
depends on ION && CMA
diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile
index a892afa..eb7eeed 100644
--- a/drivers/staging/android/ion/Makefile
+++ b/drivers/staging/android/ion/Makefile
@@ -1,4 +1,5 @@
-obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o \
- ion_page_pool.o ion_system_heap.o \
- ion_carveout_heap.o ion_chunk_heap.o
+obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o
+obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o
+obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o
+obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o
obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index e1fb865..7d40233 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -40,6 +40,9 @@
#include "ion.h"
+static struct ion_device *internal_dev;
+static int heap_id = 0;
+
bool ion_buffer_cached(struct ion_buffer *buffer)
{
return !!(buffer->flags & ION_FLAG_CACHED);
@@ -1198,9 +1201,10 @@ static int debug_shrink_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
debug_shrink_set, "%llu\n");
-void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
+void ion_device_add_heap(struct ion_heap *heap)
{
struct dentry *debug_file;
+ struct ion_device *dev = internal_dev;
if (!heap->ops->allocate || !heap->ops->free)
pr_err("%s: can not add heap with invalid ops struct.\n",
@@ -1217,6 +1221,7 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
heap->dev = dev;
down_write(&dev->lock);
+ heap->id = heap_id++;
/*
* use negative heap->id to reverse the priority -- when traversing
* the list later attempt higher id numbers first
@@ -1256,14 +1261,14 @@ void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
}
EXPORT_SYMBOL(ion_device_add_heap);
-struct ion_device *ion_device_create(void)
+int ion_device_create(void)
{
struct ion_device *idev;
int ret;
idev = kzalloc(sizeof(*idev), GFP_KERNEL);
if (!idev)
- return ERR_PTR(-ENOMEM);
+ return -ENOMEM;
idev->dev.minor = MISC_DYNAMIC_MINOR;
idev->dev.name = "ion";
@@ -1273,7 +1278,7 @@ struct ion_device *ion_device_create(void)
if (ret) {
pr_err("ion: failed to register misc device.\n");
kfree(idev);
- return ERR_PTR(ret);
+ return ret;
}
idev->debug_root = debugfs_create_dir("ion", NULL);
@@ -1292,7 +1297,6 @@ struct ion_device *ion_device_create(void)
pr_err("ion: failed to create debugfs clients directory.\n");
debugfs_done:
-
idev->buffers = RB_ROOT;
mutex_init(&idev->buffer_lock);
init_rwsem(&idev->lock);
@@ -1300,15 +1304,7 @@ struct ion_device *ion_device_create(void)
idev->clients = RB_ROOT;
ion_root_client = &idev->clients;
mutex_init(&debugfs_mutex);
- return idev;
-}
-EXPORT_SYMBOL(ion_device_create);
-
-void ion_device_destroy(struct ion_device *dev)
-{
- misc_deregister(&dev->dev);
- debugfs_remove_recursive(dev->debug_root);
- /* XXX need to free the heaps and clients ? */
- kfree(dev);
+ internal_dev = idev;
+ return 0;
}
-EXPORT_SYMBOL(ion_device_destroy);
+subsys_initcall(ion_device_create);
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index 67fcb73..27b08c8 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -280,24 +280,10 @@ bool ion_buffer_cached(struct ion_buffer *buffer);
bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer);
/**
- * ion_device_create - allocates and returns an ion device
- *
- * returns a valid device or -PTR_ERR
- */
-struct ion_device *ion_device_create(void);
-
-/**
- * ion_device_destroy - free and device and it's resource
- * @dev: the device
- */
-void ion_device_destroy(struct ion_device *dev);
-
-/**
* ion_device_add_heap - adds a heap to the ion device
- * @dev: the device
* @heap: the heap to add
*/
-void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap);
+void ion_device_add_heap(struct ion_heap *heap);
/**
* some helpers for common operations on buffers using the sg_table
@@ -390,30 +376,6 @@ size_t ion_heap_freelist_size(struct ion_heap *heap);
/**
- * functions for creating and destroying the built in ion heaps.
- * architectures can add their own custom architecture specific
- * heaps as appropriate.
- */
-
-
-struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data);
-void ion_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused);
-void ion_system_heap_destroy(struct ion_heap *heap);
-struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *heap);
-void ion_system_contig_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data);
-void ion_carveout_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data);
-void ion_chunk_heap_destroy(struct ion_heap *heap);
-
-struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data);
-void ion_cma_heap_destroy(struct ion_heap *heap);
-
-/**
* functions for creating and destroying a heap pool -- allows you
* 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
diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c
index 7287279..5fdc1f3 100644
--- a/drivers/staging/android/ion/ion_carveout_heap.c
+++ b/drivers/staging/android/ion/ion_carveout_heap.c
@@ -145,13 +145,3 @@ struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
return &carveout_heap->heap;
}
-
-void ion_carveout_heap_destroy(struct ion_heap *heap)
-{
- struct ion_carveout_heap *carveout_heap =
- container_of(heap, struct ion_carveout_heap, heap);
-
- gen_pool_destroy(carveout_heap->pool);
- kfree(carveout_heap);
- carveout_heap = NULL;
-}
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 9210bfe..9c257c7 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -160,12 +160,3 @@ struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data)
return ERR_PTR(ret);
}
-void ion_chunk_heap_destroy(struct ion_heap *heap)
-{
- struct ion_chunk_heap *chunk_heap =
- container_of(heap, struct ion_chunk_heap, heap);
-
- gen_pool_destroy(chunk_heap->pool);
- kfree(chunk_heap);
- chunk_heap = NULL;
-}
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index e67e78d..dc2a913 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -87,7 +87,7 @@ static struct ion_heap_ops ion_cma_ops = {
.unmap_kernel = ion_heap_unmap_kernel,
};
-struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
+static struct ion_heap *__ion_cma_heap_create(struct cma *cma)
{
struct ion_cma_heap *cma_heap;
@@ -101,14 +101,28 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
* get device from private heaps data, later it will be
* used to make the link with reserved CMA memory
*/
- cma_heap->cma = data->priv;
+ cma_heap->cma = cma;
cma_heap->heap.type = ION_HEAP_TYPE_DMA;
return &cma_heap->heap;
}
-void ion_cma_heap_destroy(struct ion_heap *heap)
+int __ion_add_cma_heaps(struct cma *cma, void *data)
{
- struct ion_cma_heap *cma_heap = to_cma_heap(heap);
+ struct ion_heap *heap;
+
+ heap = __ion_cma_heap_create(cma);
+ if (IS_ERR(heap))
+ return PTR_ERR(heap);
- kfree(cma_heap);
+ heap->name = cma_get_name(cma);
+
+ ion_device_add_heap(heap);
+ return 0;
+}
+
+static int ion_add_cma_heaps(void)
+{
+ cma_for_each_area(__ion_add_cma_heaps, NULL);
+ return 0;
}
+device_initcall(ion_add_cma_heaps);
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index acb292c..91faa7f 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -314,70 +314,3 @@ void ion_heap_init_shrinker(struct ion_heap *heap)
heap->shrinker.batch = 0;
register_shrinker(&heap->shrinker);
}
-
-struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
-{
- struct ion_heap *heap = NULL;
-
- switch (heap_data->type) {
- case ION_HEAP_TYPE_SYSTEM_CONTIG:
- heap = ion_system_contig_heap_create(heap_data);
- break;
- case ION_HEAP_TYPE_SYSTEM:
- heap = ion_system_heap_create(heap_data);
- break;
- case ION_HEAP_TYPE_CARVEOUT:
- heap = ion_carveout_heap_create(heap_data);
- break;
- case ION_HEAP_TYPE_CHUNK:
- heap = ion_chunk_heap_create(heap_data);
- break;
- case ION_HEAP_TYPE_DMA:
- heap = ion_cma_heap_create(heap_data);
- break;
- default:
- pr_err("%s: Invalid heap type %d\n", __func__,
- heap_data->type);
- return ERR_PTR(-EINVAL);
- }
-
- if (IS_ERR_OR_NULL(heap)) {
- pr_err("%s: error creating heap %s type %d base %pa size %zu\n",
- __func__, heap_data->name, heap_data->type,
- &heap_data->base, heap_data->size);
- return ERR_PTR(-EINVAL);
- }
-
- heap->name = heap_data->name;
- heap->id = heap_data->id;
- return heap;
-}
-EXPORT_SYMBOL(ion_heap_create);
-
-void ion_heap_destroy(struct ion_heap *heap)
-{
- if (!heap)
- return;
-
- switch (heap->type) {
- case ION_HEAP_TYPE_SYSTEM_CONTIG:
- ion_system_contig_heap_destroy(heap);
- break;
- case ION_HEAP_TYPE_SYSTEM:
- ion_system_heap_destroy(heap);
- break;
- case ION_HEAP_TYPE_CARVEOUT:
- ion_carveout_heap_destroy(heap);
- break;
- case ION_HEAP_TYPE_CHUNK:
- ion_chunk_heap_destroy(heap);
- break;
- case ION_HEAP_TYPE_DMA:
- ion_cma_heap_destroy(heap);
- break;
- default:
- pr_err("%s: Invalid heap type %d\n", __func__,
- heap->type);
- }
-}
-EXPORT_SYMBOL(ion_heap_destroy);
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 4e6fe37..c50f2d9 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -320,7 +320,7 @@ static int ion_system_heap_create_pools(struct ion_page_pool **pools,
return -ENOMEM;
}
-struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
+static struct ion_heap *__ion_system_heap_create(void)
{
struct ion_system_heap *heap;
@@ -348,19 +348,19 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
return ERR_PTR(-ENOMEM);
}
-void ion_system_heap_destroy(struct ion_heap *heap)
+static int ion_system_heap_create(void)
{
- struct ion_system_heap *sys_heap = container_of(heap,
- struct ion_system_heap,
- heap);
- int i;
+ struct ion_heap *heap;
- for (i = 0; i < NUM_ORDERS; i++) {
- ion_page_pool_destroy(sys_heap->uncached_pools[i]);
- ion_page_pool_destroy(sys_heap->cached_pools[i]);
- }
- kfree(sys_heap);
+ heap = __ion_system_heap_create();
+ if (IS_ERR(heap))
+ return PTR_ERR(heap);
+ heap->name = "ion_system_heap";
+
+ ion_device_add_heap(heap);
+ return 0;
}
+device_initcall(ion_system_heap_create);
static int ion_system_contig_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
@@ -429,7 +429,7 @@ static struct ion_heap_ops kmalloc_ops = {
.map_user = ion_heap_map_user,
};
-struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
+static struct ion_heap *__ion_system_contig_heap_create(void)
{
struct ion_heap *heap;
@@ -438,10 +438,20 @@ struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
return ERR_PTR(-ENOMEM);
heap->ops = &kmalloc_ops;
heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
+ heap->name = "ion_system_contig_heap";
return heap;
}
-void ion_system_contig_heap_destroy(struct ion_heap *heap)
+static int ion_system_contig_heap_create(void)
{
- kfree(heap);
+ struct ion_heap *heap;
+
+ heap = __ion_system_contig_heap_create();
+ if (IS_ERR(heap))
+ return PTR_ERR(heap);
+
+ ion_device_add_heap(heap);
+ return 0;
}
+device_initcall(ion_system_contig_heap_create);
+
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 02:30 +0100 |
| Subject | [RFC PATCHv2 14/21] staging: android: ion: Stop butchering the DMA address |
| Message-ID | <tmblT-77o-7@gated-at.bofh.it> |
| In reply to | #1603700 |
Now that we have proper caching, stop setting the DMA address manually.
It should be set after properly calling dma_map.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 3d979ef5..65638f5 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -81,8 +81,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
{
struct ion_buffer *buffer;
struct sg_table *table;
- struct scatterlist *sg;
- int i, ret;
+ int ret;
buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
if (!buffer)
@@ -119,20 +118,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
INIT_LIST_HEAD(&buffer->vmas);
INIT_LIST_HEAD(&buffer->attachments);
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
- */
- for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) {
- sg_dma_address(sg) = sg_phys(sg);
- sg_dma_len(sg) = sg->length;
- }
mutex_lock(&dev->buffer_lock);
ion_buffer_add(dev, buffer);
mutex_unlock(&dev->buffer_lock);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 02:50 +0100 |
| Subject | [RFC PATCHv2 02/21] cma: Introduce cma_for_each_area |
| Message-ID | <tmbFf-7g0-7@gated-at.bofh.it> |
| In reply to | #1603700 |
Frameworks (e.g. Ion) may want to iterate over each possible CMA area to
allow for enumeration. Introduce a function to allow a callback.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
include/linux/cma.h | 2 ++
mm/cma.c | 14 ++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/cma.h b/include/linux/cma.h
index d41d1f8..3e8fbf5 100644
--- a/include/linux/cma.h
+++ b/include/linux/cma.h
@@ -34,4 +34,6 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align,
gfp_t gfp_mask);
extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count);
+
+extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data);
#endif
diff --git a/mm/cma.c b/mm/cma.c
index 0d187b1..9a040e1 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -498,3 +498,17 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned int count)
return true;
}
+
+int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data)
+{
+ int i;
+
+ for (i = 0; i < cma_area_count; i++) {
+ int ret = it(&cma_areas[i], data);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 03:10 +0100 |
| Subject | [RFC PATCHv2 11/21] staging: android: ion: Remove duplicate ION_IOC_MAP |
| Message-ID | <tmbYB-7BX-3@gated-at.bofh.it> |
| In reply to | #1603700 |
ION_IOC_MAP is the same as ION_IOC_SHARE. We really don't need two
identical interfaces. Remove it.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/compat_ion.c | 1 -
drivers/staging/android/ion/ion-ioctl.c | 1 -
drivers/staging/android/uapi/ion.h | 10 ----------
3 files changed, 12 deletions(-)
diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c
index ae1ffc3..5037ddd 100644
--- a/drivers/staging/android/ion/compat_ion.c
+++ b/drivers/staging/android/ion/compat_ion.c
@@ -144,7 +144,6 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
(unsigned long)data);
}
case ION_IOC_SHARE:
- case ION_IOC_MAP:
return filp->f_op->unlocked_ioctl(filp, cmd,
(unsigned long)compat_ptr(arg));
default:
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index 7b54eea..a361724 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -118,7 +118,6 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
}
case ION_IOC_SHARE:
- case ION_IOC_MAP:
{
struct ion_handle *handle;
diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h
index 3a59044..abd72fd 100644
--- a/drivers/staging/android/uapi/ion.h
+++ b/drivers/staging/android/uapi/ion.h
@@ -164,16 +164,6 @@ struct ion_heap_query {
#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data)
/**
- * DOC: ION_IOC_MAP - get a file descriptor to mmap
- *
- * Takes an ion_fd_data struct with the handle field populated with a valid
- * opaque handle. Returns the struct with the fd field set to a file
- * descriptor open in the current address space. This file descriptor
- * can then be used as an argument to mmap.
- */
-#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data)
-
-/**
* DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation
*
* Takes an ion_fd_data struct with the handle field populated with a valid
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 03:10 +0100 |
| Subject | [RFC PATCHv2 20/21] staging: android: ion: Remove ion_handle and ion_client |
| Message-ID | <tmbYB-7BX-1@gated-at.bofh.it> |
| In reply to | #1603700 |
ion_handle was introduced as an abstraction to represent a reference to
a buffer via an ion_client. As frameworks outside of Ion evolved, the dmabuf
emerged as the preferred standard for use in the kernel. This has made
the ion_handle an unnecessary abstraction and prone to race
conditions. ion_client is also now only used internally. We have enough
mechanisms for race conditions and leaks already so just drop ion_handle
and ion_client. This also includes ripping out most of the debugfs
infrastructure since much of that was tied to clients and handles.
The debugfs infrastructure was prone to give confusing data (orphaned
allocations) so it can be replaced with something better if people
actually want it.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion-ioctl.c | 53 +--
drivers/staging/android/ion/ion.c | 697 ++------------------------------
drivers/staging/android/ion/ion.h | 73 +---
drivers/staging/android/uapi/ion.h | 25 +-
4 files changed, 49 insertions(+), 799 deletions(-)
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index 4e7bf16..76427e4 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -21,9 +21,7 @@
#include "ion.h"
union ion_ioctl_arg {
- struct ion_fd_data fd;
struct ion_allocation_data allocation;
- struct ion_handle_data handle;
struct ion_heap_query query;
};
@@ -48,8 +46,6 @@ static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg)
static unsigned int ion_ioctl_dir(unsigned int cmd)
{
switch (cmd) {
- case ION_IOC_FREE:
- return _IOC_WRITE;
default:
return _IOC_DIR(cmd);
}
@@ -57,8 +53,6 @@ static unsigned int ion_ioctl_dir(unsigned int cmd)
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- struct ion_client *client = filp->private_data;
- struct ion_handle *cleanup_handle = NULL;
int ret = 0;
unsigned int dir;
union ion_ioctl_arg data;
@@ -86,61 +80,28 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
switch (cmd) {
case ION_IOC_ALLOC:
{
- struct ion_handle *handle;
+ int fd;
- handle = ion_alloc(client, data.allocation.len,
+ fd = ion_alloc(data.allocation.len,
data.allocation.heap_id_mask,
data.allocation.flags);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
+ if (fd < 0)
+ return fd;
- data.allocation.handle = handle->id;
+ data.allocation.fd = fd;
- cleanup_handle = handle;
- break;
- }
- case ION_IOC_FREE:
- {
- struct ion_handle *handle;
-
- mutex_lock(&client->lock);
- handle = ion_handle_get_by_id_nolock(client,
- data.handle.handle);
- if (IS_ERR(handle)) {
- mutex_unlock(&client->lock);
- return PTR_ERR(handle);
- }
- ion_free_nolock(client, handle);
- ion_handle_put_nolock(handle);
- mutex_unlock(&client->lock);
- break;
- }
- case ION_IOC_SHARE:
- {
- struct ion_handle *handle;
-
- handle = ion_handle_get_by_id(client, data.handle.handle);
- if (IS_ERR(handle))
- return PTR_ERR(handle);
- data.fd.fd = ion_share_dma_buf_fd(client, handle);
- ion_handle_put(handle);
- if (data.fd.fd < 0)
- ret = data.fd.fd;
break;
}
case ION_IOC_HEAP_QUERY:
- ret = ion_query_heaps(client, &data.query);
+ ret = ion_query_heaps(&data.query);
break;
default:
return -ENOTTY;
}
if (dir & _IOC_READ) {
- if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
- if (cleanup_handle)
- ion_free(client, cleanup_handle);
+ if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd)))
return -EFAULT;
- }
}
return ret;
}
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 5a82bea..64c652b 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -90,7 +90,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->heap = heap;
buffer->flags = flags;
- kref_init(&buffer->ref);
ret = heap->ops->allocate(heap, buffer, len, flags);
@@ -140,9 +139,8 @@ void ion_buffer_destroy(struct ion_buffer *buffer)
kfree(buffer);
}
-static void _ion_buffer_destroy(struct kref *kref)
+static void _ion_buffer_destroy(struct ion_buffer *buffer)
{
- struct ion_buffer *buffer = container_of(kref, struct ion_buffer, ref);
struct ion_heap *heap = buffer->heap;
struct ion_device *dev = buffer->dev;
@@ -156,255 +154,6 @@ static void _ion_buffer_destroy(struct kref *kref)
ion_buffer_destroy(buffer);
}
-static void ion_buffer_get(struct ion_buffer *buffer)
-{
- kref_get(&buffer->ref);
-}
-
-static int ion_buffer_put(struct ion_buffer *buffer)
-{
- return kref_put(&buffer->ref, _ion_buffer_destroy);
-}
-
-static void ion_buffer_add_to_handle(struct ion_buffer *buffer)
-{
- mutex_lock(&buffer->lock);
- buffer->handle_count++;
- mutex_unlock(&buffer->lock);
-}
-
-static void ion_buffer_remove_from_handle(struct ion_buffer *buffer)
-{
- /*
- * when a buffer is removed from a handle, if it is not in
- * any other handles, copy the taskcomm and the pid of the
- * process it's being removed from into the buffer. At this
- * point there will be no way to track what processes this buffer is
- * being used by, it only exists as a dma_buf file descriptor.
- * The taskcomm and pid can provide a debug hint as to where this fd
- * is in the system
- */
- mutex_lock(&buffer->lock);
- buffer->handle_count--;
- BUG_ON(buffer->handle_count < 0);
- if (!buffer->handle_count) {
- struct task_struct *task;
-
- task = current->group_leader;
- get_task_comm(buffer->task_comm, task);
- buffer->pid = task_pid_nr(task);
- }
- mutex_unlock(&buffer->lock);
-}
-
-static struct ion_handle *ion_handle_create(struct ion_client *client,
- struct ion_buffer *buffer)
-{
- struct ion_handle *handle;
-
- handle = kzalloc(sizeof(*handle), GFP_KERNEL);
- if (!handle)
- return ERR_PTR(-ENOMEM);
- kref_init(&handle->ref);
- RB_CLEAR_NODE(&handle->node);
- handle->client = client;
- ion_buffer_get(buffer);
- ion_buffer_add_to_handle(buffer);
- handle->buffer = buffer;
-
- return handle;
-}
-
-static void ion_handle_kmap_put(struct ion_handle *);
-
-static void ion_handle_destroy(struct kref *kref)
-{
- struct ion_handle *handle = container_of(kref, struct ion_handle, ref);
- struct ion_client *client = handle->client;
- struct ion_buffer *buffer = handle->buffer;
-
- mutex_lock(&buffer->lock);
- while (handle->kmap_cnt)
- ion_handle_kmap_put(handle);
- mutex_unlock(&buffer->lock);
-
- idr_remove(&client->idr, handle->id);
- if (!RB_EMPTY_NODE(&handle->node))
- rb_erase(&handle->node, &client->handles);
-
- ion_buffer_remove_from_handle(buffer);
- ion_buffer_put(buffer);
-
- kfree(handle);
-}
-
-static void ion_handle_get(struct ion_handle *handle)
-{
- kref_get(&handle->ref);
-}
-
-int ion_handle_put_nolock(struct ion_handle *handle)
-{
- return kref_put(&handle->ref, ion_handle_destroy);
-}
-
-int ion_handle_put(struct ion_handle *handle)
-{
- struct ion_client *client = handle->client;
- int ret;
-
- mutex_lock(&client->lock);
- ret = ion_handle_put_nolock(handle);
- mutex_unlock(&client->lock);
-
- return ret;
-}
-
-struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
- int id)
-{
- struct ion_handle *handle;
-
- handle = idr_find(&client->idr, id);
- if (handle)
- ion_handle_get(handle);
-
- return handle ? handle : ERR_PTR(-EINVAL);
-}
-
-struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
- int id)
-{
- struct ion_handle *handle;
-
- mutex_lock(&client->lock);
- handle = ion_handle_get_by_id_nolock(client, id);
- mutex_unlock(&client->lock);
-
- return handle;
-}
-
-static bool ion_handle_validate(struct ion_client *client,
- struct ion_handle *handle)
-{
- WARN_ON(!mutex_is_locked(&client->lock));
- return idr_find(&client->idr, handle->id) == handle;
-}
-
-static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
-{
- int id;
- struct rb_node **p = &client->handles.rb_node;
- struct rb_node *parent = NULL;
- struct ion_handle *entry;
-
- id = idr_alloc(&client->idr, handle, 1, 0, GFP_KERNEL);
- if (id < 0)
- return id;
-
- handle->id = id;
-
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct ion_handle, node);
-
- if (handle->buffer < entry->buffer)
- p = &(*p)->rb_left;
- else if (handle->buffer > entry->buffer)
- p = &(*p)->rb_right;
- else
- WARN(1, "%s: buffer already found.", __func__);
- }
-
- rb_link_node(&handle->node, parent, p);
- rb_insert_color(&handle->node, &client->handles);
-
- return 0;
-}
-
-struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- unsigned int heap_id_mask,
- unsigned int flags)
-{
- struct ion_handle *handle;
- struct ion_device *dev = client->dev;
- struct ion_buffer *buffer = NULL;
- struct ion_heap *heap;
- int ret;
-
- pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__,
- len, heap_id_mask, flags);
- /*
- * traverse the list of heaps available in this system in priority
- * order. If the heap type is supported by the client, and matches the
- * request of the caller allocate from it. Repeat until allocate has
- * succeeded or all heaps have been tried
- */
- len = PAGE_ALIGN(len);
-
- if (!len)
- return ERR_PTR(-EINVAL);
-
- down_read(&dev->lock);
- plist_for_each_entry(heap, &dev->heaps, node) {
- /* if the caller didn't specify this heap id */
- if (!((1 << heap->id) & heap_id_mask))
- continue;
- buffer = ion_buffer_create(heap, dev, len, flags);
- if (!IS_ERR(buffer))
- break;
- }
- up_read(&dev->lock);
-
- if (buffer == NULL)
- return ERR_PTR(-ENODEV);
-
- if (IS_ERR(buffer))
- return ERR_CAST(buffer);
-
- handle = ion_handle_create(client, buffer);
-
- /*
- * ion_buffer_create will create a buffer with a ref_cnt of 1,
- * and ion_handle_create will take a second reference, drop one here
- */
- ion_buffer_put(buffer);
-
- if (IS_ERR(handle))
- return handle;
-
- mutex_lock(&client->lock);
- ret = ion_handle_add(client, handle);
- mutex_unlock(&client->lock);
- if (ret) {
- ion_handle_put(handle);
- handle = ERR_PTR(ret);
- }
-
- return handle;
-}
-EXPORT_SYMBOL(ion_alloc);
-
-void ion_free_nolock(struct ion_client *client,
- struct ion_handle *handle)
-{
- if (!ion_handle_validate(client, handle)) {
- WARN(1, "%s: invalid handle passed to free.\n", __func__);
- return;
- }
- ion_handle_put_nolock(handle);
-}
-
-void ion_free(struct ion_client *client, struct ion_handle *handle)
-{
- BUG_ON(client != handle->client);
-
- mutex_lock(&client->lock);
- ion_free_nolock(client, handle);
- mutex_unlock(&client->lock);
-}
-EXPORT_SYMBOL(ion_free);
-
static void *ion_buffer_kmap_get(struct ion_buffer *buffer)
{
void *vaddr;
@@ -433,234 +182,6 @@ static void ion_buffer_kmap_put(struct ion_buffer *buffer)
}
}
-static void ion_handle_kmap_put(struct ion_handle *handle)
-{
- struct ion_buffer *buffer = handle->buffer;
-
- if (!handle->kmap_cnt) {
- WARN(1, "%s: Double unmap detected! bailing...\n", __func__);
- return;
- }
- handle->kmap_cnt--;
- if (!handle->kmap_cnt)
- ion_buffer_kmap_put(buffer);
-}
-
-static struct mutex debugfs_mutex;
-static struct rb_root *ion_root_client;
-static int is_client_alive(struct ion_client *client)
-{
- struct rb_node *node;
- struct ion_client *tmp;
- struct ion_device *dev;
-
- node = ion_root_client->rb_node;
- dev = container_of(ion_root_client, struct ion_device, clients);
-
- down_read(&dev->lock);
- while (node) {
- tmp = rb_entry(node, struct ion_client, node);
- if (client < tmp) {
- node = node->rb_left;
- } else if (client > tmp) {
- node = node->rb_right;
- } else {
- up_read(&dev->lock);
- return 1;
- }
- }
-
- up_read(&dev->lock);
- return 0;
-}
-
-static int ion_debug_client_show(struct seq_file *s, void *unused)
-{
- struct ion_client *client = s->private;
- struct rb_node *n;
- size_t sizes[ION_NUM_HEAP_IDS] = {0};
- const char *names[ION_NUM_HEAP_IDS] = {NULL};
- int i;
-
- mutex_lock(&debugfs_mutex);
- if (!is_client_alive(client)) {
- seq_printf(s, "ion_client 0x%p dead, can't dump its buffers\n",
- client);
- mutex_unlock(&debugfs_mutex);
- return 0;
- }
-
- mutex_lock(&client->lock);
- for (n = rb_first(&client->handles); n; n = rb_next(n)) {
- struct ion_handle *handle = rb_entry(n, struct ion_handle,
- node);
- unsigned int id = handle->buffer->heap->id;
-
- if (!names[id])
- names[id] = handle->buffer->heap->name;
- sizes[id] += handle->buffer->size;
- }
- mutex_unlock(&client->lock);
- mutex_unlock(&debugfs_mutex);
-
- seq_printf(s, "%16.16s: %16.16s\n", "heap_name", "size_in_bytes");
- for (i = 0; i < ION_NUM_HEAP_IDS; i++) {
- if (!names[i])
- continue;
- seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]);
- }
- return 0;
-}
-
-static int ion_debug_client_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ion_debug_client_show, inode->i_private);
-}
-
-static const struct file_operations debug_client_fops = {
- .open = ion_debug_client_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int ion_get_client_serial(const struct rb_root *root,
- const unsigned char *name)
-{
- int serial = -1;
- struct rb_node *node;
-
- for (node = rb_first(root); node; node = rb_next(node)) {
- struct ion_client *client = rb_entry(node, struct ion_client,
- node);
-
- if (strcmp(client->name, name))
- continue;
- serial = max(serial, client->display_serial);
- }
- return serial + 1;
-}
-
-struct ion_client *ion_client_create(struct ion_device *dev,
- const char *name)
-{
- struct ion_client *client;
- struct task_struct *task;
- struct rb_node **p;
- struct rb_node *parent = NULL;
- struct ion_client *entry;
- pid_t pid;
-
- if (!name) {
- pr_err("%s: Name cannot be null\n", __func__);
- return ERR_PTR(-EINVAL);
- }
-
- 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
- */
- if (current->group_leader->flags & PF_KTHREAD) {
- put_task_struct(current->group_leader);
- task = NULL;
- } else {
- task = current->group_leader;
- }
- task_unlock(current->group_leader);
-
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (!client)
- goto err_put_task_struct;
-
- client->dev = dev;
- client->handles = RB_ROOT;
- idr_init(&client->idr);
- mutex_init(&client->lock);
- client->task = task;
- client->pid = pid;
- client->name = kstrdup(name, GFP_KERNEL);
- if (!client->name)
- goto err_free_client;
-
- down_write(&dev->lock);
- client->display_serial = ion_get_client_serial(&dev->clients, name);
- client->display_name = kasprintf(
- GFP_KERNEL, "%s-%d", name, client->display_serial);
- if (!client->display_name) {
- up_write(&dev->lock);
- goto err_free_client_name;
- }
- p = &dev->clients.rb_node;
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct ion_client, node);
-
- if (client < entry)
- p = &(*p)->rb_left;
- else if (client > entry)
- p = &(*p)->rb_right;
- }
- rb_link_node(&client->node, parent, p);
- rb_insert_color(&client->node, &dev->clients);
-
- client->debug_root = debugfs_create_file(client->display_name, 0664,
- dev->clients_debug_root,
- client, &debug_client_fops);
- if (!client->debug_root) {
- char buf[256], *path;
-
- path = dentry_path(dev->clients_debug_root, buf, 256);
- pr_err("Failed to create client debugfs at %s/%s\n",
- path, client->display_name);
- }
-
- up_write(&dev->lock);
-
- return client;
-
-err_free_client_name:
- kfree(client->name);
-err_free_client:
- kfree(client);
-err_put_task_struct:
- if (task)
- put_task_struct(current->group_leader);
- return ERR_PTR(-ENOMEM);
-}
-EXPORT_SYMBOL(ion_client_create);
-
-void ion_client_destroy(struct ion_client *client)
-{
- struct ion_device *dev = client->dev;
- struct rb_node *n;
-
- pr_debug("%s: %d\n", __func__, __LINE__);
- mutex_lock(&debugfs_mutex);
- while ((n = rb_first(&client->handles))) {
- struct ion_handle *handle = rb_entry(n, struct ion_handle,
- node);
- ion_handle_destroy(&handle->ref);
- }
-
- idr_destroy(&client->idr);
-
- down_write(&dev->lock);
- if (client->task)
- put_task_struct(client->task);
- rb_erase(&client->node, &dev->clients);
- debugfs_remove_recursive(client->debug_root);
- up_write(&dev->lock);
-
- kfree(client->display_name);
- kfree(client->name);
- kfree(client);
- mutex_unlock(&debugfs_mutex);
-}
-EXPORT_SYMBOL(ion_client_destroy);
-
static struct sg_table *dup_sg_table(struct sg_table *table)
{
struct sg_table *new_table;
@@ -802,7 +323,7 @@ static void ion_dma_buf_release(struct dma_buf *dmabuf)
{
struct ion_buffer *buffer = dmabuf->priv;
- ion_buffer_put(buffer);
+ _ion_buffer_destroy(buffer);
}
static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
@@ -881,24 +402,44 @@ static const struct dma_buf_ops dma_buf_ops = {
.kunmap = ion_dma_buf_kunmap,
};
-struct dma_buf *ion_share_dma_buf(struct ion_client *client,
- struct ion_handle *handle)
+int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags)
{
+ struct ion_device *dev = internal_dev;
+ struct ion_buffer *buffer = NULL;
+ struct ion_heap *heap;
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
- struct ion_buffer *buffer;
+ int fd;
struct dma_buf *dmabuf;
- bool valid_handle;
- mutex_lock(&client->lock);
- valid_handle = ion_handle_validate(client, handle);
- if (!valid_handle) {
- WARN(1, "%s: invalid handle passed to share.\n", __func__);
- mutex_unlock(&client->lock);
- return ERR_PTR(-EINVAL);
+ pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__,
+ len, heap_id_mask, flags);
+ /*
+ * traverse the list of heaps available in this system in priority
+ * order. If the heap type is supported by the client, and matches the
+ * request of the caller allocate from it. Repeat until allocate has
+ * succeeded or all heaps have been tried
+ */
+ len = PAGE_ALIGN(len);
+
+ if (!len)
+ return -EINVAL;
+
+ down_read(&dev->lock);
+ plist_for_each_entry(heap, &dev->heaps, node) {
+ /* if the caller didn't specify this heap id */
+ if (!((1 << heap->id) & heap_id_mask))
+ continue;
+ buffer = ion_buffer_create(heap, dev, len, flags);
+ if (!IS_ERR(buffer))
+ break;
}
- buffer = handle->buffer;
- ion_buffer_get(buffer);
- mutex_unlock(&client->lock);
+ up_read(&dev->lock);
+
+ if (buffer == NULL)
+ return -ENODEV;
+
+ if (IS_ERR(buffer))
+ return PTR_ERR(buffer);
exp_info.ops = &dma_buf_ops;
exp_info.size = buffer->size;
@@ -907,22 +448,9 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client,
dmabuf = dma_buf_export(&exp_info);
if (IS_ERR(dmabuf)) {
- ion_buffer_put(buffer);
- return dmabuf;
- }
-
- return dmabuf;
-}
-EXPORT_SYMBOL(ion_share_dma_buf);
-
-int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
-{
- struct dma_buf *dmabuf;
- int fd;
-
- dmabuf = ion_share_dma_buf(client, handle);
- if (IS_ERR(dmabuf))
+ _ion_buffer_destroy(buffer);
return PTR_ERR(dmabuf);
+ }
fd = dma_buf_fd(dmabuf, O_CLOEXEC);
if (fd < 0)
@@ -930,11 +458,10 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
return fd;
}
-EXPORT_SYMBOL(ion_share_dma_buf_fd);
-int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
+int ion_query_heaps(struct ion_heap_query *query)
{
- struct ion_device *dev = client->dev;
+ struct ion_device *dev = internal_dev;
struct ion_heap_data __user *buffer = u64_to_user_ptr(query->heaps);
int ret = -EINVAL, cnt = 0, max_cnt;
struct ion_heap *heap;
@@ -976,137 +503,14 @@ int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
return ret;
}
-static int ion_release(struct inode *inode, struct file *file)
-{
- struct ion_client *client = file->private_data;
-
- pr_debug("%s: %d\n", __func__, __LINE__);
- ion_client_destroy(client);
- return 0;
-}
-
-static int ion_open(struct inode *inode, struct file *file)
-{
- struct miscdevice *miscdev = file->private_data;
- struct ion_device *dev = container_of(miscdev, struct ion_device, dev);
- struct ion_client *client;
- char debug_name[64];
-
- pr_debug("%s: %d\n", __func__, __LINE__);
- snprintf(debug_name, 64, "%u", task_pid_nr(current->group_leader));
- client = ion_client_create(dev, debug_name);
- if (IS_ERR(client))
- return PTR_ERR(client);
- file->private_data = client;
-
- return 0;
-}
-
static const struct file_operations ion_fops = {
.owner = THIS_MODULE,
- .open = ion_open,
- .release = ion_release,
.unlocked_ioctl = ion_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ion_ioctl,
#endif
};
-static size_t ion_debug_heap_total(struct ion_client *client,
- unsigned int id)
-{
- size_t size = 0;
- struct rb_node *n;
-
- mutex_lock(&client->lock);
- for (n = rb_first(&client->handles); n; n = rb_next(n)) {
- struct ion_handle *handle = rb_entry(n,
- struct ion_handle,
- node);
- if (handle->buffer->heap->id == id)
- size += handle->buffer->size;
- }
- mutex_unlock(&client->lock);
- return size;
-}
-
-static int ion_debug_heap_show(struct seq_file *s, void *unused)
-{
- struct ion_heap *heap = s->private;
- struct ion_device *dev = heap->dev;
- struct rb_node *n;
- size_t total_size = 0;
- size_t total_orphaned_size = 0;
-
- seq_printf(s, "%16s %16s %16s\n", "client", "pid", "size");
- seq_puts(s, "----------------------------------------------------\n");
-
- mutex_lock(&debugfs_mutex);
- for (n = rb_first(&dev->clients); n; n = rb_next(n)) {
- struct ion_client *client = rb_entry(n, struct ion_client,
- node);
- size_t size = ion_debug_heap_total(client, heap->id);
-
- if (!size)
- continue;
- if (client->task) {
- char task_comm[TASK_COMM_LEN];
-
- get_task_comm(task_comm, client->task);
- seq_printf(s, "%16s %16u %16zu\n", task_comm,
- client->pid, size);
- } else {
- seq_printf(s, "%16s %16u %16zu\n", client->name,
- client->pid, size);
- }
- }
- mutex_unlock(&debugfs_mutex);
-
- seq_puts(s, "----------------------------------------------------\n");
- seq_puts(s, "orphaned allocations (info is from last known client):\n");
- mutex_lock(&dev->buffer_lock);
- for (n = rb_first(&dev->buffers); n; n = rb_next(n)) {
- struct ion_buffer *buffer = rb_entry(n, struct ion_buffer,
- node);
- if (buffer->heap->id != heap->id)
- continue;
- total_size += buffer->size;
- if (!buffer->handle_count) {
- seq_printf(s, "%16s %16u %16zu %d %d\n",
- buffer->task_comm, buffer->pid,
- buffer->size, buffer->kmap_cnt,
- kref_read(&buffer->ref));
- total_orphaned_size += buffer->size;
- }
- }
- mutex_unlock(&dev->buffer_lock);
- seq_puts(s, "----------------------------------------------------\n");
- seq_printf(s, "%16s %16zu\n", "total orphaned",
- total_orphaned_size);
- seq_printf(s, "%16s %16zu\n", "total ", total_size);
- if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
- seq_printf(s, "%16s %16zu\n", "deferred free",
- heap->free_list_size);
- seq_puts(s, "----------------------------------------------------\n");
-
- if (heap->debug_show)
- heap->debug_show(heap, s, unused);
-
- return 0;
-}
-
-static int ion_debug_heap_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ion_debug_heap_show, inode->i_private);
-}
-
-static const struct file_operations debug_heap_fops = {
- .open = ion_debug_heap_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static int debug_shrink_set(void *data, u64 val)
{
struct ion_heap *heap = data;
@@ -1169,17 +573,6 @@ void ion_device_add_heap(struct ion_heap *heap)
*/
plist_node_init(&heap->node, -heap->id);
plist_add(&heap->node, &dev->heaps);
- debug_file = debugfs_create_file(heap->name, 0664,
- dev->heaps_debug_root, heap,
- &debug_heap_fops);
-
- if (!debug_file) {
- char buf[256], *path;
-
- path = dentry_path(dev->heaps_debug_root, buf, 256);
- pr_err("Failed to create heap debugfs at %s/%s\n",
- path, heap->name);
- }
if (heap->shrinker.count_objects && heap->shrinker.scan_objects) {
char debug_name[64];
@@ -1227,24 +620,12 @@ int ion_device_create(void)
pr_err("ion: failed to create debugfs root directory.\n");
goto debugfs_done;
}
- idev->heaps_debug_root = debugfs_create_dir("heaps", idev->debug_root);
- if (!idev->heaps_debug_root) {
- pr_err("ion: failed to create debugfs heaps directory.\n");
- goto debugfs_done;
- }
- idev->clients_debug_root = debugfs_create_dir("clients",
- idev->debug_root);
- if (!idev->clients_debug_root)
- pr_err("ion: failed to create debugfs clients directory.\n");
debugfs_done:
idev->buffers = RB_ROOT;
mutex_init(&idev->buffer_lock);
init_rwsem(&idev->lock);
plist_head_init(&idev->heaps);
- idev->clients = RB_ROOT;
- ion_root_client = &idev->clients;
- mutex_init(&debugfs_mutex);
internal_dev = idev;
return 0;
}
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index 27b08c8..410cc86 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -78,7 +78,6 @@ struct ion_platform_heap {
* handle, used for debugging
*/
struct ion_buffer {
- struct kref ref;
union {
struct rb_node node;
struct list_head list;
@@ -118,7 +117,6 @@ struct ion_device {
struct mutex buffer_lock;
struct rw_semaphore lock;
struct plist_head heaps;
- struct rb_root clients;
struct dentry *debug_root;
struct dentry *heaps_debug_root;
struct dentry *clients_debug_root;
@@ -126,57 +124,6 @@ struct ion_device {
};
/**
- * struct ion_client - a process/hw block local address space
- * @node: node in the tree of all clients
- * @dev: backpointer to ion device
- * @handles: an rb tree of all the handles in this client
- * @idr: an idr space for allocating handle ids
- * @lock: lock protecting the tree of handles
- * @name: used for debugging
- * @display_name: used for debugging (unique version of @name)
- * @display_serial: used for debugging (to make display_name unique)
- * @task: used for debugging
- *
- * A client represents a list of buffers this client may access.
- * The mutex stored here is used to protect both handles tree
- * as well as the handles themselves, and should be held while modifying either.
- */
-struct ion_client {
- struct rb_node node;
- struct ion_device *dev;
- struct rb_root handles;
- struct idr idr;
- struct mutex lock;
- const char *name;
- char *display_name;
- int display_serial;
- struct task_struct *task;
- pid_t pid;
- struct dentry *debug_root;
-};
-
-/**
- * ion_handle - a client local reference to a buffer
- * @ref: reference count
- * @client: back pointer to the client the buffer resides in
- * @buffer: pointer to the buffer
- * @node: node in the client's handle rbtree
- * @kmap_cnt: count of times this client has mapped to kernel
- * @id: client-unique id allocated by client->idr
- *
- * Modifications to node, map_cnt or mapping should be protected by the
- * lock in the client. Other fields are never changed after initialization.
- */
-struct ion_handle {
- struct kref ref;
- struct ion_client *client;
- struct ion_buffer *buffer;
- struct rb_node node;
- unsigned int kmap_cnt;
- int id;
-};
-
-/**
* struct ion_heap_ops - ops to operate on a given heap
* @allocate: allocate memory
* @free: free memory
@@ -296,14 +243,10 @@ int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
int ion_heap_buffer_zero(struct ion_buffer *buffer);
int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
-struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
+int ion_alloc(size_t len,
unsigned int heap_id_mask,
unsigned int flags);
-void ion_free(struct ion_client *client, struct ion_handle *handle);
-
-int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle);
-
/**
* ion_heap_init_shrinker
* @heap: the heap
@@ -431,18 +374,6 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask,
long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
-struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
- int id);
-
-void ion_free_nolock(struct ion_client *client, struct ion_handle *handle);
-
-int ion_handle_put_nolock(struct ion_handle *handle);
-
-struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
- int id);
-
-int ion_handle_put(struct ion_handle *handle);
-
-int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query);
+int ion_query_heaps(struct ion_heap_query *query);
#endif /* _ION_PRIV_H */
diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h
index bba1c47..b76db1b 100644
--- a/drivers/staging/android/uapi/ion.h
+++ b/drivers/staging/android/uapi/ion.h
@@ -85,31 +85,8 @@ struct ion_allocation_data {
__u64 len;
__u32 heap_id_mask;
__u32 flags;
- __u32 handle;
- __u32 unused;
-};
-
-/**
- * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair
- * @handle: a handle
- * @fd: a file descriptor representing that handle
- *
- * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with
- * the handle returned from ion alloc, and the kernel returns the file
- * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace
- * provides the file descriptor and the kernel returns the handle.
- */
-struct ion_fd_data {
- __u32 handle;
__u32 fd;
-};
-
-/**
- * struct ion_handle_data - a handle passed to/from the kernel
- * @handle: a handle
- */
-struct ion_handle_data {
- __u32 handle;
+ __u32 unused;
};
#define MAX_HEAP_NAME 32
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 03:50 +0100 |
| Subject | [RFC PATCHv2 07/21] staging: android: ion: Remove page faulting support |
| Message-ID | <tmcBj-7Ty-1@gated-at.bofh.it> |
| In reply to | #1603700 |
The new method of syncing with dma_map means that the page faulting sync
implementation is no longer applicable. Remove it.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion.c | 117 --------------------------------------
1 file changed, 117 deletions(-)
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 6aac935..226ea1f 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -42,37 +42,11 @@
#include "ion_priv.h"
#include "compat_ion.h"
-bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
-{
- return (buffer->flags & ION_FLAG_CACHED) &&
- !(buffer->flags & ION_FLAG_CACHED_NEEDS_SYNC);
-}
-
bool ion_buffer_cached(struct ion_buffer *buffer)
{
return !!(buffer->flags & ION_FLAG_CACHED);
}
-static inline struct page *ion_buffer_page(struct page *page)
-{
- return (struct page *)((unsigned long)page & ~(1UL));
-}
-
-static inline bool ion_buffer_page_is_dirty(struct page *page)
-{
- return !!((unsigned long)page & 1UL);
-}
-
-static inline void ion_buffer_page_dirty(struct page **page)
-{
- *page = (struct page *)((unsigned long)(*page) | 1UL);
-}
-
-static inline void ion_buffer_page_clean(struct page **page)
-{
- *page = (struct page *)((unsigned long)(*page) & ~(1UL));
-}
-
/* this function should only be called while dev->lock is held */
static void ion_buffer_add(struct ion_device *dev,
struct ion_buffer *buffer)
@@ -140,25 +114,6 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->dev = dev;
buffer->size = len;
- if (ion_buffer_fault_user_mappings(buffer)) {
- int num_pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
- struct scatterlist *sg;
- int i, j, k = 0;
-
- buffer->pages = vmalloc(sizeof(struct page *) * num_pages);
- if (!buffer->pages) {
- ret = -ENOMEM;
- goto err1;
- }
-
- for_each_sg(table->sgl, sg, table->nents, i) {
- struct page *page = sg_page(sg);
-
- for (j = 0; j < sg->length / PAGE_SIZE; j++)
- buffer->pages[k++] = page++;
- }
- }
-
buffer->dev = dev;
buffer->size = len;
INIT_LIST_HEAD(&buffer->vmas);
@@ -924,69 +879,6 @@ void ion_pages_sync_for_device(struct device *dev, struct page *page,
dma_sync_sg_for_device(dev, &sg, 1, dir);
}
-struct ion_vma_list {
- struct list_head list;
- struct vm_area_struct *vma;
-};
-
-static int ion_vm_fault(struct vm_fault *vmf)
-{
- struct ion_buffer *buffer = vmf->vma->vm_private_data;
- unsigned long pfn;
- int ret;
-
- mutex_lock(&buffer->lock);
- ion_buffer_page_dirty(buffer->pages + vmf->pgoff);
- BUG_ON(!buffer->pages || !buffer->pages[vmf->pgoff]);
-
- pfn = page_to_pfn(ion_buffer_page(buffer->pages[vmf->pgoff]));
- ret = vm_insert_pfn(vmf->vma, vmf->address, pfn);
- mutex_unlock(&buffer->lock);
- if (ret)
- return VM_FAULT_ERROR;
-
- return VM_FAULT_NOPAGE;
-}
-
-static void ion_vm_open(struct vm_area_struct *vma)
-{
- struct ion_buffer *buffer = vma->vm_private_data;
- struct ion_vma_list *vma_list;
-
- vma_list = kmalloc(sizeof(*vma_list), GFP_KERNEL);
- if (!vma_list)
- return;
- vma_list->vma = vma;
- mutex_lock(&buffer->lock);
- list_add(&vma_list->list, &buffer->vmas);
- mutex_unlock(&buffer->lock);
- pr_debug("%s: adding %p\n", __func__, vma);
-}
-
-static void ion_vm_close(struct vm_area_struct *vma)
-{
- struct ion_buffer *buffer = vma->vm_private_data;
- struct ion_vma_list *vma_list, *tmp;
-
- pr_debug("%s\n", __func__);
- mutex_lock(&buffer->lock);
- list_for_each_entry_safe(vma_list, tmp, &buffer->vmas, list) {
- if (vma_list->vma != vma)
- continue;
- list_del(&vma_list->list);
- kfree(vma_list);
- pr_debug("%s: deleting %p\n", __func__, vma);
- break;
- }
- mutex_unlock(&buffer->lock);
-}
-
-static const struct vm_operations_struct ion_vma_ops = {
- .open = ion_vm_open,
- .close = ion_vm_close,
- .fault = ion_vm_fault,
-};
-
static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
{
struct ion_buffer *buffer = dmabuf->priv;
@@ -998,15 +890,6 @@ static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
return -EINVAL;
}
- if (ion_buffer_fault_user_mappings(buffer)) {
- vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND |
- VM_DONTDUMP;
- vma->vm_private_data = buffer;
- vma->vm_ops = &ion_vma_ops;
- ion_vm_open(vma);
- return 0;
- }
-
if (!(buffer->flags & ION_FLAG_CACHED))
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 04:00 +0100 |
| Subject | [RFC PATCHv2 10/21] staging: android: ion: Remove import interface |
| Message-ID | <tmcKZ-7ZW-3@gated-at.bofh.it> |
| In reply to | #1603700 |
With the expansion of dma-buf and the move for Ion to be come just an
allocator, the import mechanism is mostly useless. There isn't a kernel
component to Ion anymore and handles are private to Ion. Remove this
interface.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/compat_ion.c | 1 -
drivers/staging/android/ion/ion-ioctl.c | 11 -----
drivers/staging/android/ion/ion.c | 76 --------------------------------
drivers/staging/android/uapi/ion.h | 9 ----
4 files changed, 97 deletions(-)
diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c
index 5b192ea..ae1ffc3 100644
--- a/drivers/staging/android/ion/compat_ion.c
+++ b/drivers/staging/android/ion/compat_ion.c
@@ -145,7 +145,6 @@ long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
case ION_IOC_SHARE:
case ION_IOC_MAP:
- case ION_IOC_IMPORT:
return filp->f_op->unlocked_ioctl(filp, cmd,
(unsigned long)compat_ptr(arg));
default:
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index 2b475bf..7b54eea 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -131,17 +131,6 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
ret = data.fd.fd;
break;
}
- case ION_IOC_IMPORT:
- {
- struct ion_handle *handle;
-
- handle = ion_import_dma_buf_fd(client, data.fd.fd);
- if (IS_ERR(handle))
- ret = PTR_ERR(handle);
- else
- data.handle.handle = handle->id;
- break;
- }
case ION_IOC_HEAP_QUERY:
ret = ion_query_heaps(client, &data.query);
break;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 125c537..3d979ef5 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -274,24 +274,6 @@ int ion_handle_put(struct ion_handle *handle)
return ret;
}
-static struct ion_handle *ion_handle_lookup(struct ion_client *client,
- struct ion_buffer *buffer)
-{
- struct rb_node *n = client->handles.rb_node;
-
- while (n) {
- struct ion_handle *entry = rb_entry(n, struct ion_handle, node);
-
- if (buffer < entry->buffer)
- n = n->rb_left;
- else if (buffer > entry->buffer)
- n = n->rb_right;
- else
- return entry;
- }
- return ERR_PTR(-EINVAL);
-}
-
struct ion_handle *ion_handle_get_by_id_nolock(struct ion_client *client,
int id)
{
@@ -1023,64 +1005,6 @@ int ion_share_dma_buf_fd(struct ion_client *client, struct ion_handle *handle)
}
EXPORT_SYMBOL(ion_share_dma_buf_fd);
-struct ion_handle *ion_import_dma_buf(struct ion_client *client,
- struct dma_buf *dmabuf)
-{
- struct ion_buffer *buffer;
- struct ion_handle *handle;
- int ret;
-
- /* if this memory came from ion */
-
- if (dmabuf->ops != &dma_buf_ops) {
- pr_err("%s: can not import dmabuf from another exporter\n",
- __func__);
- return ERR_PTR(-EINVAL);
- }
- buffer = dmabuf->priv;
-
- mutex_lock(&client->lock);
- /* if a handle exists for this buffer just take a reference to it */
- handle = ion_handle_lookup(client, buffer);
- if (!IS_ERR(handle)) {
- ion_handle_get(handle);
- mutex_unlock(&client->lock);
- goto end;
- }
-
- handle = ion_handle_create(client, buffer);
- if (IS_ERR(handle)) {
- mutex_unlock(&client->lock);
- goto end;
- }
-
- ret = ion_handle_add(client, handle);
- mutex_unlock(&client->lock);
- if (ret) {
- ion_handle_put(handle);
- handle = ERR_PTR(ret);
- }
-
-end:
- return handle;
-}
-EXPORT_SYMBOL(ion_import_dma_buf);
-
-struct ion_handle *ion_import_dma_buf_fd(struct ion_client *client, int fd)
-{
- struct dma_buf *dmabuf;
- struct ion_handle *handle;
-
- dmabuf = dma_buf_get(fd);
- if (IS_ERR(dmabuf))
- return ERR_CAST(dmabuf);
-
- handle = ion_import_dma_buf(client, dmabuf);
- dma_buf_put(dmabuf);
- return handle;
-}
-EXPORT_SYMBOL(ion_import_dma_buf_fd);
-
int ion_query_heaps(struct ion_client *client, struct ion_heap_query *query)
{
struct ion_device *dev = client->dev;
diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h
index 8ff471d..3a59044 100644
--- a/drivers/staging/android/uapi/ion.h
+++ b/drivers/staging/android/uapi/ion.h
@@ -185,15 +185,6 @@ struct ion_heap_query {
#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data)
/**
- * DOC: ION_IOC_IMPORT - imports a shared file descriptor
- *
- * Takes an ion_fd_data struct with the fd field populated with a valid file
- * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle
- * filed set to the corresponding opaque handle.
- */
-#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data)
-
-/**
* DOC: ION_IOC_HEAP_QUERY - information about available heaps
*
* Takes an ion_heap_query structure and populates information about
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 04:00 +0100 |
| Subject | [RFC PATCHv2 03/21] staging: android: ion: Remove dmap_cnt |
| Message-ID | <tmcKZ-7ZW-1@gated-at.bofh.it> |
| In reply to | #1603700 |
The reference counting of dma_map calls was removed. Remove the
associated counter field as well.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion_priv.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 5b3059c..46d3ff5 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -44,7 +44,6 @@
* @lock: protects the buffers cnt fields
* @kmap_cnt: number of times the buffer is mapped to the kernel
* @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
* handler and only valid for buffers that are faulted in
@@ -70,7 +69,6 @@ struct ion_buffer {
struct mutex lock;
int kmap_cnt;
void *vaddr;
- int dmap_cnt;
struct sg_table *sg_table;
struct page **pages;
struct list_head vmas;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 04:10 +0100 |
| Subject | [RFC PATCHv2 15/21] staging: android: ion: Break the ABI in the name of forward progress |
| Message-ID | <tmcUF-8ir-1@gated-at.bofh.it> |
| In reply to | #1603700 |
To: Sumit Semwal <sumit.semwal@linaro.org>
To: Riley Andrews <riandrews@android.com>
Cc: romlem@google.com
To: arve@android.com
To: Riley Andrews <riandrews@android.com>
Cc: devel@driverdev.osuosl.org
Cc: linux-kernel@vger.kernel.org
Cc: linaro-mm-sig@lists.linaro.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: Brian Starkey <brian.starkey@arm.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Cc: linux-mm@kvack.org
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Several of the Ion ioctls were designed in such a way that they
necessitate compat ioctls. We're breaking a bunch of other ABIs and
cleaning stuff up anyway so let's follow the ioctl guidelines and clean
things up while everyone is busy converting things over anyway. As part
of this, also remove the useless alignment field from the allocation
structure.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/Makefile | 3 -
drivers/staging/android/ion/compat_ion.c | 152 -------------------------------
drivers/staging/android/ion/compat_ion.h | 29 ------
drivers/staging/android/ion/ion-ioctl.c | 1 -
drivers/staging/android/ion/ion.c | 5 +-
drivers/staging/android/uapi/ion.h | 19 ++--
6 files changed, 11 insertions(+), 198 deletions(-)
delete mode 100644 drivers/staging/android/ion/compat_ion.c
delete mode 100644 drivers/staging/android/ion/compat_ion.h
diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile
index 66d0c4a..a892afa 100644
--- a/drivers/staging/android/ion/Makefile
+++ b/drivers/staging/android/ion/Makefile
@@ -2,6 +2,3 @@ obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o \
ion_page_pool.o ion_system_heap.o \
ion_carveout_heap.o ion_chunk_heap.o
obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
-ifdef CONFIG_COMPAT
-obj-$(CONFIG_ION) += compat_ion.o
-endif
diff --git a/drivers/staging/android/ion/compat_ion.c b/drivers/staging/android/ion/compat_ion.c
deleted file mode 100644
index 5037ddd..0000000
--- a/drivers/staging/android/ion/compat_ion.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * drivers/staging/android/ion/compat_ion.c
- *
- * Copyright (C) 2013 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/compat.h>
-#include <linux/fs.h>
-#include <linux/uaccess.h>
-
-#include "ion.h"
-#include "compat_ion.h"
-
-/* See drivers/staging/android/uapi/ion.h for the definition of these structs */
-struct compat_ion_allocation_data {
- compat_size_t len;
- compat_size_t align;
- compat_uint_t heap_id_mask;
- compat_uint_t flags;
- compat_int_t handle;
-};
-
-struct compat_ion_handle_data {
- compat_int_t handle;
-};
-
-#define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
- struct compat_ion_allocation_data)
-#define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \
- struct compat_ion_handle_data)
-
-static int compat_get_ion_allocation_data(
- struct compat_ion_allocation_data __user *data32,
- struct ion_allocation_data __user *data)
-{
- compat_size_t s;
- compat_uint_t u;
- compat_int_t i;
- int err;
-
- err = get_user(s, &data32->len);
- err |= put_user(s, &data->len);
- err |= get_user(s, &data32->align);
- err |= put_user(s, &data->align);
- err |= get_user(u, &data32->heap_id_mask);
- err |= put_user(u, &data->heap_id_mask);
- err |= get_user(u, &data32->flags);
- err |= put_user(u, &data->flags);
- err |= get_user(i, &data32->handle);
- err |= put_user(i, &data->handle);
-
- return err;
-}
-
-static int compat_get_ion_handle_data(
- struct compat_ion_handle_data __user *data32,
- struct ion_handle_data __user *data)
-{
- compat_int_t i;
- int err;
-
- err = get_user(i, &data32->handle);
- err |= put_user(i, &data->handle);
-
- return err;
-}
-
-static int compat_put_ion_allocation_data(
- struct compat_ion_allocation_data __user *data32,
- struct ion_allocation_data __user *data)
-{
- compat_size_t s;
- compat_uint_t u;
- compat_int_t i;
- int err;
-
- err = get_user(s, &data->len);
- err |= put_user(s, &data32->len);
- err |= get_user(s, &data->align);
- err |= put_user(s, &data32->align);
- err |= get_user(u, &data->heap_id_mask);
- err |= put_user(u, &data32->heap_id_mask);
- err |= get_user(u, &data->flags);
- err |= put_user(u, &data32->flags);
- err |= get_user(i, &data->handle);
- err |= put_user(i, &data32->handle);
-
- return err;
-}
-
-long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- long ret;
-
- if (!filp->f_op->unlocked_ioctl)
- return -ENOTTY;
-
- switch (cmd) {
- case COMPAT_ION_IOC_ALLOC:
- {
- struct compat_ion_allocation_data __user *data32;
- struct ion_allocation_data __user *data;
- int err;
-
- data32 = compat_ptr(arg);
- data = compat_alloc_user_space(sizeof(*data));
- if (!data)
- return -EFAULT;
-
- err = compat_get_ion_allocation_data(data32, data);
- if (err)
- return err;
- ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
- (unsigned long)data);
- err = compat_put_ion_allocation_data(data32, data);
- return ret ? ret : err;
- }
- case COMPAT_ION_IOC_FREE:
- {
- struct compat_ion_handle_data __user *data32;
- struct ion_handle_data __user *data;
- int err;
-
- data32 = compat_ptr(arg);
- data = compat_alloc_user_space(sizeof(*data));
- if (!data)
- return -EFAULT;
-
- err = compat_get_ion_handle_data(data32, data);
- if (err)
- return err;
-
- return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
- (unsigned long)data);
- }
- case ION_IOC_SHARE:
- return filp->f_op->unlocked_ioctl(filp, cmd,
- (unsigned long)compat_ptr(arg));
- default:
- return -ENOIOCTLCMD;
- }
-}
diff --git a/drivers/staging/android/ion/compat_ion.h b/drivers/staging/android/ion/compat_ion.h
deleted file mode 100644
index 9da8f91..0000000
--- a/drivers/staging/android/ion/compat_ion.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * drivers/staging/android/ion/compat_ion.h
- *
- * Copyright (C) 2013 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _LINUX_COMPAT_ION_H
-#define _LINUX_COMPAT_ION_H
-
-#if IS_ENABLED(CONFIG_COMPAT)
-
-long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
-
-#else
-
-#define compat_ion_ioctl NULL
-
-#endif /* CONFIG_COMPAT */
-#endif /* _LINUX_COMPAT_ION_H */
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index a361724..91b5c2b 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -20,7 +20,6 @@
#include "ion.h"
#include "ion_priv.h"
-#include "compat_ion.h"
union ion_ioctl_arg {
struct ion_fd_data fd;
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 65638f5..fbab1e3 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -40,7 +40,6 @@
#include "ion.h"
#include "ion_priv.h"
-#include "compat_ion.h"
bool ion_buffer_cached(struct ion_buffer *buffer)
{
@@ -1065,7 +1064,9 @@ static const struct file_operations ion_fops = {
.open = ion_open,
.release = ion_release,
.unlocked_ioctl = ion_ioctl,
- .compat_ioctl = compat_ion_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ion_ioctl,
+#endif
};
static size_t ion_debug_heap_total(struct ion_client *client,
diff --git a/drivers/staging/android/uapi/ion.h b/drivers/staging/android/uapi/ion.h
index abd72fd..bba1c47 100644
--- a/drivers/staging/android/uapi/ion.h
+++ b/drivers/staging/android/uapi/ion.h
@@ -20,8 +20,6 @@
#include <linux/ioctl.h>
#include <linux/types.h>
-typedef int ion_user_handle_t;
-
/**
* enum ion_heap_types - list of all possible types of heaps
* @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc
@@ -76,7 +74,6 @@ enum ion_heap_type {
/**
* struct ion_allocation_data - metadata passed from userspace for allocations
* @len: size of the allocation
- * @align: required alignment of the allocation
* @heap_id_mask: mask of heap ids to allocate from
* @flags: flags passed to heap
* @handle: pointer that will be populated with a cookie to use to
@@ -85,11 +82,11 @@ enum ion_heap_type {
* Provided by userspace as an argument to the ioctl
*/
struct ion_allocation_data {
- size_t len;
- size_t align;
- unsigned int heap_id_mask;
- unsigned int flags;
- ion_user_handle_t handle;
+ __u64 len;
+ __u32 heap_id_mask;
+ __u32 flags;
+ __u32 handle;
+ __u32 unused;
};
/**
@@ -103,8 +100,8 @@ struct ion_allocation_data {
* provides the file descriptor and the kernel returns the handle.
*/
struct ion_fd_data {
- ion_user_handle_t handle;
- int fd;
+ __u32 handle;
+ __u32 fd;
};
/**
@@ -112,7 +109,7 @@ struct ion_fd_data {
* @handle: a handle
*/
struct ion_handle_data {
- ion_user_handle_t handle;
+ __u32 handle;
};
#define MAX_HEAP_NAME 32
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 04:40 +0100 |
| Subject | [RFC PATCHv2 21/21] staging: android: ion: Set query return value |
| Message-ID | <tmdnH-9c-1@gated-at.bofh.it> |
| In reply to | #1603700 |
This never got set in the ioctl. Properly set a return value of 0 on success. Signed-off-by: Laura Abbott <labbott@redhat.com> --- drivers/staging/android/ion/ion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 64c652b..8bd90ce 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -498,6 +498,7 @@ int ion_query_heaps(struct ion_heap_query *query) } query->cnt = cnt; + ret = 0; out: up_read(&dev->lock); return ret; -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 05:00 +0100 |
| Subject | [RFC PATCHv2 04/21] staging: android: ion: Remove alignment from allocation field |
| Message-ID | <tmdH4-hD-3@gated-at.bofh.it> |
| In reply to | #1603700 |
The align field was supposed to be used to specify the alignment of
the allocation. Nobody actually does anything with it except to check
if the alignment specified is out of bounds. Since this has no effect
on the actual allocation, just remove it.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion-ioctl.c | 1 -
drivers/staging/android/ion/ion.c | 14 ++++++--------
drivers/staging/android/ion/ion.h | 5 +----
drivers/staging/android/ion/ion_carveout_heap.c | 10 +++-------
drivers/staging/android/ion/ion_chunk_heap.c | 9 +++------
drivers/staging/android/ion/ion_cma_heap.c | 5 +----
drivers/staging/android/ion/ion_priv.h | 2 +-
drivers/staging/android/ion/ion_system_heap.c | 9 +--------
8 files changed, 16 insertions(+), 39 deletions(-)
diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c
index 9ff815a..5b2e93f 100644
--- a/drivers/staging/android/ion/ion-ioctl.c
+++ b/drivers/staging/android/ion/ion-ioctl.c
@@ -95,7 +95,6 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct ion_handle *handle;
handle = ion_alloc(client, data.allocation.len,
- data.allocation.align,
data.allocation.heap_id_mask,
data.allocation.flags);
if (IS_ERR(handle))
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index f45115f..c2adfe1 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -103,7 +103,6 @@ static void ion_buffer_add(struct ion_device *dev,
static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
struct ion_device *dev,
unsigned long len,
- unsigned long align,
unsigned long flags)
{
struct ion_buffer *buffer;
@@ -119,15 +118,14 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->flags = flags;
kref_init(&buffer->ref);
- ret = heap->ops->allocate(heap, buffer, len, align, flags);
+ ret = heap->ops->allocate(heap, buffer, len, flags);
if (ret) {
if (!(heap->flags & ION_HEAP_FLAG_DEFER_FREE))
goto err2;
ion_heap_freelist_drain(heap, 0);
- ret = heap->ops->allocate(heap, buffer, len, align,
- flags);
+ ret = heap->ops->allocate(heap, buffer, len, flags);
if (ret)
goto err2;
}
@@ -401,7 +399,7 @@ static int ion_handle_add(struct ion_client *client, struct ion_handle *handle)
}
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int heap_id_mask,
+ unsigned int heap_id_mask,
unsigned int flags)
{
struct ion_handle *handle;
@@ -410,8 +408,8 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
struct ion_heap *heap;
int ret;
- pr_debug("%s: len %zu align %zu heap_id_mask %u flags %x\n", __func__,
- len, align, heap_id_mask, flags);
+ pr_debug("%s: len %zu heap_id_mask %u flags %x\n", __func__,
+ len, heap_id_mask, flags);
/*
* traverse the list of heaps available in this system in priority
* order. If the heap type is supported by the client, and matches the
@@ -428,7 +426,7 @@ struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
/* if the caller didn't specify this heap id */
if (!((1 << heap->id) & heap_id_mask))
continue;
- buffer = ion_buffer_create(heap, dev, len, align, flags);
+ buffer = ion_buffer_create(heap, dev, len, flags);
if (!IS_ERR(buffer))
break;
}
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index 93dafb4..3b4bff5 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -45,7 +45,6 @@ struct ion_buffer;
* @name: used for debug purposes
* @base: base address of heap in physical memory if applicable
* @size: size of the heap in bytes if applicable
- * @align: required alignment in physical memory if applicable
* @priv: private info passed from the board file
*
* Provided by the board file.
@@ -93,8 +92,6 @@ void ion_client_destroy(struct ion_client *client);
* ion_alloc - allocate ion memory
* @client: the client
* @len: size of the allocation
- * @align: requested allocation alignment, lots of hardware blocks
- * have alignment requirements of some kind
* @heap_id_mask: mask of heaps to allocate from, if multiple bits are set
* heaps will be tried in order from highest to lowest
* id
@@ -106,7 +103,7 @@ void ion_client_destroy(struct ion_client *client);
* an opaque handle to it.
*/
struct ion_handle *ion_alloc(struct ion_client *client, size_t len,
- size_t align, unsigned int heap_id_mask,
+ unsigned int heap_id_mask,
unsigned int flags);
/**
diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c
index a8ea973..9bf8e98 100644
--- a/drivers/staging/android/ion/ion_carveout_heap.c
+++ b/drivers/staging/android/ion/ion_carveout_heap.c
@@ -34,8 +34,7 @@ struct ion_carveout_heap {
};
static ion_phys_addr_t ion_carveout_allocate(struct ion_heap *heap,
- unsigned long size,
- unsigned long align)
+ unsigned long size)
{
struct ion_carveout_heap *carveout_heap =
container_of(heap, struct ion_carveout_heap, heap);
@@ -60,16 +59,13 @@ static void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
static int ion_carveout_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
- unsigned long size, unsigned long align,
+ unsigned long size,
unsigned long flags)
{
struct sg_table *table;
ion_phys_addr_t paddr;
int ret;
- if (align > PAGE_SIZE)
- return -EINVAL;
-
table = kmalloc(sizeof(*table), GFP_KERNEL);
if (!table)
return -ENOMEM;
@@ -77,7 +73,7 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap,
if (ret)
goto err_free;
- paddr = ion_carveout_allocate(heap, size, align);
+ paddr = ion_carveout_allocate(heap, size);
if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) {
ret = -ENOMEM;
goto err_free_table;
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 70495dc..8c41889 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -35,7 +35,7 @@ struct ion_chunk_heap {
static int ion_chunk_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
- unsigned long size, unsigned long align,
+ unsigned long size,
unsigned long flags)
{
struct ion_chunk_heap *chunk_heap =
@@ -46,9 +46,6 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap,
unsigned long num_chunks;
unsigned long allocated_size;
- if (align > chunk_heap->chunk_size)
- return -EINVAL;
-
allocated_size = ALIGN(size, chunk_heap->chunk_size);
num_chunks = allocated_size / chunk_heap->chunk_size;
@@ -160,8 +157,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_debug("%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 \n", __func__,
+ chunk_heap->base, heap_data->size);
return &chunk_heap->heap;
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index 6c40685..d562fd7 100644
--- a/drivers/staging/android/ion/ion_cma_heap.c
+++ b/drivers/staging/android/ion/ion_cma_heap.c
@@ -40,7 +40,7 @@ struct ion_cma_buffer_info {
/* ION CMA heap operations functions */
static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
- unsigned long len, unsigned long align,
+ unsigned long len,
unsigned long flags)
{
struct ion_cma_heap *cma_heap = to_cma_heap(heap);
@@ -52,9 +52,6 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
if (buffer->flags & ION_FLAG_CACHED)
return -EINVAL;
- if (align > PAGE_SIZE)
- return -EINVAL;
-
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index 46d3ff5..b09bc7c 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -172,7 +172,7 @@ struct ion_handle {
struct ion_heap_ops {
int (*allocate)(struct ion_heap *heap,
struct ion_buffer *buffer, unsigned long len,
- unsigned long align, unsigned long flags);
+ unsigned long flags);
void (*free)(struct ion_buffer *buffer);
void * (*map_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
void (*unmap_kernel)(struct ion_heap *heap, struct ion_buffer *buffer);
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 3ebbb75..6cb2fe7 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -129,7 +129,7 @@ static struct page *alloc_largest_available(struct ion_system_heap *heap,
static int ion_system_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
- unsigned long size, unsigned long align,
+ unsigned long size,
unsigned long flags)
{
struct ion_system_heap *sys_heap = container_of(heap,
@@ -143,9 +143,6 @@ static int ion_system_heap_allocate(struct ion_heap *heap,
unsigned long size_remaining = PAGE_ALIGN(size);
unsigned int max_order = orders[0];
- if (align > PAGE_SIZE)
- return -EINVAL;
-
if (size / PAGE_SIZE > totalram_pages / 2)
return -ENOMEM;
@@ -372,7 +369,6 @@ void ion_system_heap_destroy(struct ion_heap *heap)
static int ion_system_contig_heap_allocate(struct ion_heap *heap,
struct ion_buffer *buffer,
unsigned long len,
- unsigned long align,
unsigned long flags)
{
int order = get_order(len);
@@ -381,9 +377,6 @@ static int ion_system_contig_heap_allocate(struct ion_heap *heap,
unsigned long i;
int ret;
- if (align > (PAGE_SIZE << order))
- return -EINVAL;
-
page = alloc_pages(low_order_gfp_flags, order);
if (!page)
return -ENOMEM;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Laura Abbott <labbott@redhat.com> |
|---|---|
| Date | 2017-03-18 15:50 +0100 |
| Subject | [RFC PATCHv2 06/21] staging: android: ion: Call dma_map_sg for syncing and mapping |
| Message-ID | <tmnQ5-7Kg-3@gated-at.bofh.it> |
| In reply to | #1603700 |
Technically, calling dma_buf_map_attachment should return a buffer
properly dma_mapped. Add calls to dma_map_sg to begin_cpu_access to
ensure this happens. As a side effect, this lets Ion buffers take
advantage of the dma_buf sync ioctls.
Signed-off-by: Laura Abbott <labbott@redhat.com>
---
drivers/staging/android/ion/ion.c | 151 ++++++++++++++++++++++-----------
drivers/staging/android/ion/ion_priv.h | 1 +
2 files changed, 103 insertions(+), 49 deletions(-)
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 7dcb8a9..6aac935 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -162,6 +162,7 @@ static struct ion_buffer *ion_buffer_create(struct ion_heap *heap,
buffer->dev = dev;
buffer->size = len;
INIT_LIST_HEAD(&buffer->vmas);
+ INIT_LIST_HEAD(&buffer->attachments);
mutex_init(&buffer->lock);
/*
* this will set up dma addresses for the sglist -- it is not
@@ -796,10 +797,6 @@ void ion_client_destroy(struct ion_client *client)
}
EXPORT_SYMBOL(ion_client_destroy);
-static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
- struct device *dev,
- enum dma_data_direction direction);
-
static struct sg_table *dup_sg_table(struct sg_table *table)
{
struct sg_table *new_table;
@@ -826,22 +823,89 @@ static struct sg_table *dup_sg_table(struct sg_table *table)
return new_table;
}
+static void free_duped_table(struct sg_table *table)
+{
+ sg_free_table(table);
+ kfree(table);
+}
+
+struct ion_dma_buf_attachment {
+ struct device *dev;
+ struct sg_table *table;
+ struct list_head list;
+};
+
+static int ion_dma_buf_attach(struct dma_buf *dmabuf, struct device *dev,
+ struct dma_buf_attachment *attachment)
+{
+ struct ion_dma_buf_attachment *a;
+ struct sg_table *table;
+ struct ion_buffer *buffer = dmabuf->priv;
+
+ a = kzalloc(sizeof(*a), GFP_KERNEL);
+ if (!a)
+ return -ENOMEM;
+
+ table = dup_sg_table(buffer->sg_table);
+ if (IS_ERR(table)) {
+ kfree(a);
+ return -ENOMEM;
+ }
+
+ a->table = table;
+ a->dev = dev;
+ INIT_LIST_HEAD(&a->list);
+
+ attachment->priv = a;
+
+ mutex_lock(&buffer->lock);
+ list_add(&a->list, &buffer->attachments);
+ mutex_unlock(&buffer->lock);
+
+ return 0;
+}
+
+static void ion_dma_buf_detatch(struct dma_buf *dmabuf,
+ struct dma_buf_attachment *attachment)
+{
+ struct ion_dma_buf_attachment *a = attachment->priv;
+ struct ion_buffer *buffer = dmabuf->priv;
+
+ free_duped_table(a->table);
+ mutex_lock(&buffer->lock);
+ list_del(&a->list);
+ mutex_unlock(&buffer->lock);
+
+ kfree(a);
+}
+
+
static struct sg_table *ion_map_dma_buf(struct dma_buf_attachment *attachment,
enum dma_data_direction direction)
{
- struct dma_buf *dmabuf = attachment->dmabuf;
- struct ion_buffer *buffer = dmabuf->priv;
+ struct ion_dma_buf_attachment *a = attachment->priv;
+ struct sg_table *table;
+ int ret;
+
+ table = a->table;
- ion_buffer_sync_for_device(buffer, attachment->dev, direction);
- return dup_sg_table(buffer->sg_table);
+ if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
+ direction)){
+ ret = -ENOMEM;
+ goto err;
+ }
+ return table;
+
+err:
+ free_duped_table(table);
+ return ERR_PTR(ret);
}
static void ion_unmap_dma_buf(struct dma_buf_attachment *attachment,
struct sg_table *table,
enum dma_data_direction direction)
{
- sg_free_table(table);
- kfree(table);
+ dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
}
void ion_pages_sync_for_device(struct device *dev, struct page *page,
@@ -865,38 +929,6 @@ struct ion_vma_list {
struct vm_area_struct *vma;
};
-static void ion_buffer_sync_for_device(struct ion_buffer *buffer,
- struct device *dev,
- enum dma_data_direction dir)
-{
- struct ion_vma_list *vma_list;
- int pages = PAGE_ALIGN(buffer->size) / PAGE_SIZE;
- int i;
-
- pr_debug("%s: syncing for device %s\n", __func__,
- dev ? dev_name(dev) : "null");
-
- if (!ion_buffer_fault_user_mappings(buffer))
- return;
-
- mutex_lock(&buffer->lock);
- for (i = 0; i < pages; i++) {
- struct page *page = buffer->pages[i];
-
- if (ion_buffer_page_is_dirty(page))
- ion_pages_sync_for_device(dev, ion_buffer_page(page),
- PAGE_SIZE, dir);
-
- ion_buffer_page_clean(buffer->pages + i);
- }
- list_for_each_entry(vma_list, &buffer->vmas, list) {
- struct vm_area_struct *vma = vma_list->vma;
-
- zap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start);
- }
- mutex_unlock(&buffer->lock);
-}
-
static int ion_vm_fault(struct vm_fault *vmf)
{
struct ion_buffer *buffer = vmf->vma->vm_private_data;
@@ -1014,26 +1046,45 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
{
struct ion_buffer *buffer = dmabuf->priv;
void *vaddr;
+ struct ion_dma_buf_attachment *a;
- if (!buffer->heap->ops->map_kernel) {
- pr_err("%s: map kernel is not implemented by this heap.\n",
- __func__);
- return -ENODEV;
+ /*
+ * TODO: Move this elsewhere because we don't always need a vaddr
+ */
+ if (buffer->heap->ops->map_kernel) {
+ mutex_lock(&buffer->lock);
+ vaddr = ion_buffer_kmap_get(buffer);
+ mutex_unlock(&buffer->lock);
}
+
mutex_lock(&buffer->lock);
- vaddr = ion_buffer_kmap_get(buffer);
+ list_for_each_entry(a, &buffer->attachments, list) {
+ dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents,
+ DMA_BIDIRECTIONAL);
+ }
mutex_unlock(&buffer->lock);
- return PTR_ERR_OR_ZERO(vaddr);
+
+ return 0;
}
static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
enum dma_data_direction direction)
{
struct ion_buffer *buffer = dmabuf->priv;
+ struct ion_dma_buf_attachment *a;
+
+ if (buffer->heap->ops->map_kernel) {
+ mutex_lock(&buffer->lock);
+ ion_buffer_kmap_put(buffer);
+ mutex_unlock(&buffer->lock);
+ }
mutex_lock(&buffer->lock);
- ion_buffer_kmap_put(buffer);
+ list_for_each_entry(a, &buffer->attachments, list) {
+ dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents,
+ DMA_BIDIRECTIONAL);
+ }
mutex_unlock(&buffer->lock);
return 0;
@@ -1044,6 +1095,8 @@ static const struct dma_buf_ops dma_buf_ops = {
.unmap_dma_buf = ion_unmap_dma_buf,
.mmap = ion_mmap,
.release = ion_dma_buf_release,
+ .attach = ion_dma_buf_attach,
+ .detach = ion_dma_buf_detatch,
.begin_cpu_access = ion_dma_buf_begin_cpu_access,
.end_cpu_access = ion_dma_buf_end_cpu_access,
.kmap_atomic = ion_dma_buf_kmap,
diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h
index b09bc7c..297d99d 100644
--- a/drivers/staging/android/ion/ion_priv.h
+++ b/drivers/staging/android/ion/ion_priv.h
@@ -72,6 +72,7 @@ struct ion_buffer {
struct sg_table *sg_table;
struct page **pages;
struct list_head vmas;
+ struct list_head attachments;
/* used to track orphaned buffers */
int handle_count;
char task_comm[TASK_COMM_LEN];
--
2.7.4
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web