aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaura Abbott <labbott@redhat.com>2017-04-18 14:27:10 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-18 14:43:14 -0400
commit2f87f50b234038ff91f67b4a98f2289ff630563a (patch)
tree82d312ca71d3b6a7bd0dc5e2864e64547f3a455b
parenteb9751dbe6aaff217769d6bf2adc8eea684714a1 (diff)
staging: android: ion: Rework heap registration/enumeration
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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/android/ion/Kconfig25
-rw-r--r--drivers/staging/android/ion/Makefile7
-rw-r--r--drivers/staging/android/ion/ion.c28
-rw-r--r--drivers/staging/android/ion/ion.h40
-rw-r--r--drivers/staging/android/ion/ion_carveout_heap.c10
-rw-r--r--drivers/staging/android/ion/ion_chunk_heap.c9
-rw-r--r--drivers/staging/android/ion/ion_cma_heap.c24
-rw-r--r--drivers/staging/android/ion/ion_heap.c71
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c38
9 files changed, 85 insertions, 167 deletions
diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
index 15108c40c81f..a517b2d29f1b 100644
--- a/drivers/staging/android/ion/Kconfig
+++ b/drivers/staging/android/ion/Kconfig
@@ -10,6 +10,31 @@ menuconfig ION
10 If you're not using Android its probably safe to 10 If you're not using Android its probably safe to
11 say N here. 11 say N here.
12 12
13config ION_SYSTEM_HEAP
14 bool "Ion system heap"
15 depends on ION
16 help
17 Choose this option to enable the Ion system heap. The system heap
18 is backed by pages from the buddy allocator. If in doubt, say Y.
19
20config ION_CARVEOUT_HEAP
21 bool "Ion carveout heap support"
22 depends on ION
23 help
24 Choose this option to enable carveout heaps with Ion. Carveout heaps
25 are backed by memory reserved from the system. Allocation times are
26 typically faster at the cost of memory not being used. Unless you
27 know your system has these regions, you should say N here.
28
29config ION_CHUNK_HEAP
30 bool "Ion chunk heap support"
31 depends on ION
32 help
33 Choose this option to enable chunk heaps with Ion. This heap is
34 similar in function the carveout heap but memory is broken down
35 into smaller chunk sizes, typically corresponding to a TLB size.
36 Unless you know your system has these regions, you should say N here.
37
13config ION_CMA_HEAP 38config ION_CMA_HEAP
14 bool "Ion CMA heap support" 39 bool "Ion CMA heap support"
15 depends on ION && CMA 40 depends on ION && CMA
diff --git a/drivers/staging/android/ion/Makefile b/drivers/staging/android/ion/Makefile
index a892afa56819..eb7eeed6ae40 100644
--- a/drivers/staging/android/ion/Makefile
+++ b/drivers/staging/android/ion/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o \ 1obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o
2 ion_page_pool.o ion_system_heap.o \ 2obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o
3 ion_carveout_heap.o ion_chunk_heap.o 3obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o
4obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o
4obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o 5obj-$(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 e1fb86530c96..7d402334a546 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -40,6 +40,9 @@
40 40
41#include "ion.h" 41#include "ion.h"
42 42
43static struct ion_device *internal_dev;
44static int heap_id = 0;
45
43bool ion_buffer_cached(struct ion_buffer *buffer) 46bool ion_buffer_cached(struct ion_buffer *buffer)
44{ 47{
45 return !!(buffer->flags & ION_FLAG_CACHED); 48 return !!(buffer->flags & ION_FLAG_CACHED);
@@ -1198,9 +1201,10 @@ static int debug_shrink_get(void *data, u64 *val)
1198DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, 1201DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,
1199 debug_shrink_set, "%llu\n"); 1202 debug_shrink_set, "%llu\n");
1200 1203
1201void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) 1204void ion_device_add_heap(struct ion_heap *heap)
1202{ 1205{
1203 struct dentry *debug_file; 1206 struct dentry *debug_file;
1207 struct ion_device *dev = internal_dev;
1204 1208
1205 if (!heap->ops->allocate || !heap->ops->free) 1209 if (!heap->ops->allocate || !heap->ops->free)
1206 pr_err("%s: can not add heap with invalid ops struct.\n", 1210 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)
1217 1221
1218 heap->dev = dev; 1222 heap->dev = dev;
1219 down_write(&dev->lock); 1223 down_write(&dev->lock);
1224 heap->id = heap_id++;
1220 /* 1225 /*
1221 * use negative heap->id to reverse the priority -- when traversing 1226 * use negative heap->id to reverse the priority -- when traversing
1222 * the list later attempt higher id numbers first 1227 * 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)
1256} 1261}
1257EXPORT_SYMBOL(ion_device_add_heap); 1262EXPORT_SYMBOL(ion_device_add_heap);
1258 1263
1259struct ion_device *ion_device_create(void) 1264int ion_device_create(void)
1260{ 1265{
1261 struct ion_device *idev; 1266 struct ion_device *idev;
1262 int ret; 1267 int ret;
1263 1268
1264 idev = kzalloc(sizeof(*idev), GFP_KERNEL); 1269 idev = kzalloc(sizeof(*idev), GFP_KERNEL);
1265 if (!idev) 1270 if (!idev)
1266 return ERR_PTR(-ENOMEM); 1271 return -ENOMEM;
1267 1272
1268 idev->dev.minor = MISC_DYNAMIC_MINOR; 1273 idev->dev.minor = MISC_DYNAMIC_MINOR;
1269 idev->dev.name = "ion"; 1274 idev->dev.name = "ion";
@@ -1273,7 +1278,7 @@ struct ion_device *ion_device_create(void)
1273 if (ret) { 1278 if (ret) {
1274 pr_err("ion: failed to register misc device.\n"); 1279 pr_err("ion: failed to register misc device.\n");
1275 kfree(idev); 1280 kfree(idev);
1276 return ERR_PTR(ret); 1281 return ret;
1277 } 1282 }
1278 1283
1279 idev->debug_root = debugfs_create_dir("ion", NULL); 1284 idev->debug_root = debugfs_create_dir("ion", NULL);
@@ -1292,7 +1297,6 @@ struct ion_device *ion_device_create(void)
1292 pr_err("ion: failed to create debugfs clients directory.\n"); 1297 pr_err("ion: failed to create debugfs clients directory.\n");
1293 1298
1294debugfs_done: 1299debugfs_done:
1295
1296 idev->buffers = RB_ROOT; 1300 idev->buffers = RB_ROOT;
1297 mutex_init(&idev->buffer_lock); 1301 mutex_init(&idev->buffer_lock);
1298 init_rwsem(&idev->lock); 1302 init_rwsem(&idev->lock);
@@ -1300,15 +1304,7 @@ debugfs_done:
1300 idev->clients = RB_ROOT; 1304 idev->clients = RB_ROOT;
1301 ion_root_client = &idev->clients; 1305 ion_root_client = &idev->clients;
1302 mutex_init(&debugfs_mutex); 1306 mutex_init(&debugfs_mutex);
1303 return idev; 1307 internal_dev = idev;
1304} 1308 return 0;
1305EXPORT_SYMBOL(ion_device_create);
1306
1307void ion_device_destroy(struct ion_device *dev)
1308{
1309 misc_deregister(&dev->dev);
1310 debugfs_remove_recursive(dev->debug_root);
1311 /* XXX need to free the heaps and clients ? */
1312 kfree(dev);
1313} 1309}
1314EXPORT_SYMBOL(ion_device_destroy); 1310subsys_initcall(ion_device_create);
diff --git a/drivers/staging/android/ion/ion.h b/drivers/staging/android/ion/ion.h
index fd494034c390..36a15870092a 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);
280bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer); 280bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer);
281 281
282/** 282/**
283 * ion_device_create - allocates and returns an ion device
284 *
285 * returns a valid device or -PTR_ERR
286 */
287struct ion_device *ion_device_create(void);
288
289/**
290 * ion_device_destroy - free and device and it's resource
291 * @dev: the device
292 */
293void ion_device_destroy(struct ion_device *dev);
294
295/**
296 * ion_device_add_heap - adds a heap to the ion device 283 * ion_device_add_heap - adds a heap to the ion device
297 * @dev: the device
298 * @heap: the heap to add 284 * @heap: the heap to add
299 */ 285 */
300void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); 286void ion_device_add_heap(struct ion_heap *heap);
301 287
302/** 288/**
303 * some helpers for common operations on buffers using the sg_table 289 * 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);
390 376
391 377
392/** 378/**
393 * functions for creating and destroying the built in ion heaps.
394 * architectures can add their own custom architecture specific
395 * heaps as appropriate.
396 */
397
398
399struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data);
400void ion_heap_destroy(struct ion_heap *heap);
401
402struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused);
403void ion_system_heap_destroy(struct ion_heap *heap);
404struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *heap);
405void ion_system_contig_heap_destroy(struct ion_heap *heap);
406
407struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data);
408void ion_carveout_heap_destroy(struct ion_heap *heap);
409
410struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data);
411void ion_chunk_heap_destroy(struct ion_heap *heap);
412
413struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data);
414void ion_cma_heap_destroy(struct ion_heap *heap);
415
416/**
417 * functions for creating and destroying a heap pool -- allows you 379 * functions for creating and destroying a heap pool -- allows you
418 * to keep a pool of pre allocated memory to use from your heap. Keeping 380 * to keep a pool of pre allocated memory to use from your heap. Keeping
419 * a pool of memory that is ready for dma, ie any cached mapping have been 381 * 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 72872795c1e4..5fdc1f328f61 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)
145 145
146 return &carveout_heap->heap; 146 return &carveout_heap->heap;
147} 147}
148
149void ion_carveout_heap_destroy(struct ion_heap *heap)
150{
151 struct ion_carveout_heap *carveout_heap =
152 container_of(heap, struct ion_carveout_heap, heap);
153
154 gen_pool_destroy(carveout_heap->pool);
155 kfree(carveout_heap);
156 carveout_heap = NULL;
157}
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 9210bfee241c..9c257c7a2ba0 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -160,12 +160,3 @@ error_gen_pool_create:
160 return ERR_PTR(ret); 160 return ERR_PTR(ret);
161} 161}
162 162
163void ion_chunk_heap_destroy(struct ion_heap *heap)
164{
165 struct ion_chunk_heap *chunk_heap =
166 container_of(heap, struct ion_chunk_heap, heap);
167
168 gen_pool_destroy(chunk_heap->pool);
169 kfree(chunk_heap);
170 chunk_heap = NULL;
171}
diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
index e67e78da40d9..dc2a9135c4d0 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 = {
87 .unmap_kernel = ion_heap_unmap_kernel, 87 .unmap_kernel = ion_heap_unmap_kernel,
88}; 88};
89 89
90struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) 90static struct ion_heap *__ion_cma_heap_create(struct cma *cma)
91{ 91{
92 struct ion_cma_heap *cma_heap; 92 struct ion_cma_heap *cma_heap;
93 93
@@ -101,14 +101,28 @@ struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
101 * get device from private heaps data, later it will be 101 * get device from private heaps data, later it will be
102 * used to make the link with reserved CMA memory 102 * used to make the link with reserved CMA memory
103 */ 103 */
104 cma_heap->cma = data->priv; 104 cma_heap->cma = cma;
105 cma_heap->heap.type = ION_HEAP_TYPE_DMA; 105 cma_heap->heap.type = ION_HEAP_TYPE_DMA;
106 return &cma_heap->heap; 106 return &cma_heap->heap;
107} 107}
108 108
109void ion_cma_heap_destroy(struct ion_heap *heap) 109int __ion_add_cma_heaps(struct cma *cma, void *data)
110{ 110{
111 struct ion_cma_heap *cma_heap = to_cma_heap(heap); 111 struct ion_heap *heap;
112
113 heap = __ion_cma_heap_create(cma);
114 if (IS_ERR(heap))
115 return PTR_ERR(heap);
112 116
113 kfree(cma_heap); 117 heap->name = cma_get_name(cma);
118
119 ion_device_add_heap(heap);
120 return 0;
121}
122
123static int ion_add_cma_heaps(void)
124{
125 cma_for_each_area(__ion_add_cma_heaps, NULL);
126 return 0;
114} 127}
128device_initcall(ion_add_cma_heaps);
diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c
index d8d057cab206..91faa7f035b9 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -314,74 +314,3 @@ void ion_heap_init_shrinker(struct ion_heap *heap)
314 heap->shrinker.batch = 0; 314 heap->shrinker.batch = 0;
315 register_shrinker(&heap->shrinker); 315 register_shrinker(&heap->shrinker);
316} 316}
317
318struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
319{
320 struct ion_heap *heap = NULL;
321
322 switch (heap_data->type) {
323 case ION_HEAP_TYPE_SYSTEM_CONTIG:
324 heap = ion_system_contig_heap_create(heap_data);
325 break;
326 case ION_HEAP_TYPE_SYSTEM:
327 heap = ion_system_heap_create(heap_data);
328 break;
329 case ION_HEAP_TYPE_CARVEOUT:
330 heap = ion_carveout_heap_create(heap_data);
331 break;
332 case ION_HEAP_TYPE_CHUNK:
333 heap = ion_chunk_heap_create(heap_data);
334 break;
335#ifdef CONFIG_ION_CMA_HEAP
336 case ION_HEAP_TYPE_DMA:
337 heap = ion_cma_heap_create(heap_data);
338 break;
339#endif
340 default:
341 pr_err("%s: Invalid heap type %d\n", __func__,
342 heap_data->type);
343 return ERR_PTR(-EINVAL);
344 }
345
346 if (IS_ERR_OR_NULL(heap)) {
347 pr_err("%s: error creating heap %s type %d base %pa size %zu\n",
348 __func__, heap_data->name, heap_data->type,
349 &heap_data->base, heap_data->size);
350 return ERR_PTR(-EINVAL);
351 }
352
353 heap->name = heap_data->name;
354 heap->id = heap_data->id;
355 return heap;
356}
357EXPORT_SYMBOL(ion_heap_create);
358
359void ion_heap_destroy(struct ion_heap *heap)
360{
361 if (!heap)
362 return;
363
364 switch (heap->type) {
365 case ION_HEAP_TYPE_SYSTEM_CONTIG:
366 ion_system_contig_heap_destroy(heap);
367 break;
368 case ION_HEAP_TYPE_SYSTEM:
369 ion_system_heap_destroy(heap);
370 break;
371 case ION_HEAP_TYPE_CARVEOUT:
372 ion_carveout_heap_destroy(heap);
373 break;
374 case ION_HEAP_TYPE_CHUNK:
375 ion_chunk_heap_destroy(heap);
376 break;
377#ifdef CONFIG_ION_CMA_HEAP
378 case ION_HEAP_TYPE_DMA:
379 ion_cma_heap_destroy(heap);
380 break;
381#endif
382 default:
383 pr_err("%s: Invalid heap type %d\n", __func__,
384 heap->type);
385 }
386}
387EXPORT_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 4e6fe371bc0e..c50f2d9fc58c 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -320,7 +320,7 @@ err_create_pool:
320 return -ENOMEM; 320 return -ENOMEM;
321} 321}
322 322
323struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) 323static struct ion_heap *__ion_system_heap_create(void)
324{ 324{
325 struct ion_system_heap *heap; 325 struct ion_system_heap *heap;
326 326
@@ -348,19 +348,19 @@ free_heap:
348 return ERR_PTR(-ENOMEM); 348 return ERR_PTR(-ENOMEM);
349} 349}
350 350
351void ion_system_heap_destroy(struct ion_heap *heap) 351static int ion_system_heap_create(void)
352{ 352{
353 struct ion_system_heap *sys_heap = container_of(heap, 353 struct ion_heap *heap;
354 struct ion_system_heap,
355 heap);
356 int i;
357 354
358 for (i = 0; i < NUM_ORDERS; i++) { 355 heap = __ion_system_heap_create();
359 ion_page_pool_destroy(sys_heap->uncached_pools[i]); 356 if (IS_ERR(heap))
360 ion_page_pool_destroy(sys_heap->cached_pools[i]); 357 return PTR_ERR(heap);
361 } 358 heap->name = "ion_system_heap";
362 kfree(sys_heap); 359
360 ion_device_add_heap(heap);
361 return 0;
363} 362}
363device_initcall(ion_system_heap_create);
364 364
365static int ion_system_contig_heap_allocate(struct ion_heap *heap, 365static int ion_system_contig_heap_allocate(struct ion_heap *heap,
366 struct ion_buffer *buffer, 366 struct ion_buffer *buffer,
@@ -429,7 +429,7 @@ static struct ion_heap_ops kmalloc_ops = {
429 .map_user = ion_heap_map_user, 429 .map_user = ion_heap_map_user,
430}; 430};
431 431
432struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) 432static struct ion_heap *__ion_system_contig_heap_create(void)
433{ 433{
434 struct ion_heap *heap; 434 struct ion_heap *heap;
435 435
@@ -438,10 +438,20 @@ struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused)
438 return ERR_PTR(-ENOMEM); 438 return ERR_PTR(-ENOMEM);
439 heap->ops = &kmalloc_ops; 439 heap->ops = &kmalloc_ops;
440 heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; 440 heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG;
441 heap->name = "ion_system_contig_heap";
441 return heap; 442 return heap;
442} 443}
443 444
444void ion_system_contig_heap_destroy(struct ion_heap *heap) 445static int ion_system_contig_heap_create(void)
445{ 446{
446 kfree(heap); 447 struct ion_heap *heap;
448
449 heap = __ion_system_contig_heap_create();
450 if (IS_ERR(heap))
451 return PTR_ERR(heap);
452
453 ion_device_add_heap(heap);
454 return 0;
447} 455}
456device_initcall(ion_system_contig_heap_create);
457