Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Laura Abbott and committed by
Greg Kroah-Hartman
2f87f50b eb9751db

+85 -167
+25
drivers/staging/android/ion/Kconfig
··· 10 10 If you're not using Android its probably safe to 11 11 say N here. 12 12 13 + config 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 + 20 + config 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 + 29 + config 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 + 13 38 config ION_CMA_HEAP 14 39 bool "Ion CMA heap support" 15 40 depends on ION && CMA
+4 -3
drivers/staging/android/ion/Makefile
··· 1 - obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o \ 2 - ion_page_pool.o ion_system_heap.o \ 3 - ion_carveout_heap.o ion_chunk_heap.o 1 + obj-$(CONFIG_ION) += ion.o ion-ioctl.o ion_heap.o 2 + obj-$(CONFIG_ION_SYSTEM_HEAP) += ion_system_heap.o ion_page_pool.o 3 + obj-$(CONFIG_ION_CARVEOUT_HEAP) += ion_carveout_heap.o 4 + obj-$(CONFIG_ION_CHUNK_HEAP) += ion_chunk_heap.o 4 5 obj-$(CONFIG_ION_CMA_HEAP) += ion_cma_heap.o
+12 -16
drivers/staging/android/ion/ion.c
··· 40 40 41 41 #include "ion.h" 42 42 43 + static struct ion_device *internal_dev; 44 + static int heap_id = 0; 45 + 43 46 bool ion_buffer_cached(struct ion_buffer *buffer) 44 47 { 45 48 return !!(buffer->flags & ION_FLAG_CACHED); ··· 1201 1198 DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get, 1202 1199 debug_shrink_set, "%llu\n"); 1203 1200 1204 - void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap) 1201 + void ion_device_add_heap(struct ion_heap *heap) 1205 1202 { 1206 1203 struct dentry *debug_file; 1204 + struct ion_device *dev = internal_dev; 1207 1205 1208 1206 if (!heap->ops->allocate || !heap->ops->free) 1209 1207 pr_err("%s: can not add heap with invalid ops struct.\n", ··· 1221 1217 1222 1218 heap->dev = dev; 1223 1219 down_write(&dev->lock); 1220 + heap->id = heap_id++; 1224 1221 /* 1225 1222 * use negative heap->id to reverse the priority -- when traversing 1226 1223 * the list later attempt higher id numbers first ··· 1261 1256 } 1262 1257 EXPORT_SYMBOL(ion_device_add_heap); 1263 1258 1264 - struct ion_device *ion_device_create(void) 1259 + int ion_device_create(void) 1265 1260 { 1266 1261 struct ion_device *idev; 1267 1262 int ret; 1268 1263 1269 1264 idev = kzalloc(sizeof(*idev), GFP_KERNEL); 1270 1265 if (!idev) 1271 - return ERR_PTR(-ENOMEM); 1266 + return -ENOMEM; 1272 1267 1273 1268 idev->dev.minor = MISC_DYNAMIC_MINOR; 1274 1269 idev->dev.name = "ion"; ··· 1278 1273 if (ret) { 1279 1274 pr_err("ion: failed to register misc device.\n"); 1280 1275 kfree(idev); 1281 - return ERR_PTR(ret); 1276 + return ret; 1282 1277 } 1283 1278 1284 1279 idev->debug_root = debugfs_create_dir("ion", NULL); ··· 1297 1292 pr_err("ion: failed to create debugfs clients directory.\n"); 1298 1293 1299 1294 debugfs_done: 1300 - 1301 1295 idev->buffers = RB_ROOT; 1302 1296 mutex_init(&idev->buffer_lock); 1303 1297 init_rwsem(&idev->lock); ··· 1304 1300 idev->clients = RB_ROOT; 1305 1301 ion_root_client = &idev->clients; 1306 1302 mutex_init(&debugfs_mutex); 1307 - return idev; 1303 + internal_dev = idev; 1304 + return 0; 1308 1305 } 1309 - EXPORT_SYMBOL(ion_device_create); 1310 - 1311 - void ion_device_destroy(struct ion_device *dev) 1312 - { 1313 - misc_deregister(&dev->dev); 1314 - debugfs_remove_recursive(dev->debug_root); 1315 - /* XXX need to free the heaps and clients ? */ 1316 - kfree(dev); 1317 - } 1318 - EXPORT_SYMBOL(ion_device_destroy); 1306 + subsys_initcall(ion_device_create);
+1 -39
drivers/staging/android/ion/ion.h
··· 280 280 bool 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 - */ 287 - struct ion_device *ion_device_create(void); 288 - 289 - /** 290 - * ion_device_destroy - free and device and it's resource 291 - * @dev: the device 292 - */ 293 - void ion_device_destroy(struct ion_device *dev); 294 - 295 - /** 296 283 * ion_device_add_heap - adds a heap to the ion device 297 - * @dev: the device 298 284 * @heap: the heap to add 299 285 */ 300 - void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap); 286 + void ion_device_add_heap(struct ion_heap *heap); 301 287 302 288 /** 303 289 * some helpers for common operations on buffers using the sg_table ··· 374 388 */ 375 389 size_t ion_heap_freelist_size(struct ion_heap *heap); 376 390 377 - 378 - /** 379 - * functions for creating and destroying the built in ion heaps. 380 - * architectures can add their own custom architecture specific 381 - * heaps as appropriate. 382 - */ 383 - 384 - 385 - struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data); 386 - void ion_heap_destroy(struct ion_heap *heap); 387 - 388 - struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused); 389 - void ion_system_heap_destroy(struct ion_heap *heap); 390 - struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *heap); 391 - void ion_system_contig_heap_destroy(struct ion_heap *heap); 392 - 393 - struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data); 394 - void ion_carveout_heap_destroy(struct ion_heap *heap); 395 - 396 - struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *heap_data); 397 - void ion_chunk_heap_destroy(struct ion_heap *heap); 398 - 399 - struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data); 400 - void ion_cma_heap_destroy(struct ion_heap *heap); 401 391 402 392 /** 403 393 * functions for creating and destroying a heap pool -- allows you
-10
drivers/staging/android/ion/ion_carveout_heap.c
··· 145 145 146 146 return &carveout_heap->heap; 147 147 } 148 - 149 - void 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 - }
-9
drivers/staging/android/ion/ion_chunk_heap.c
··· 160 160 return ERR_PTR(ret); 161 161 } 162 162 163 - void 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 - }
+19 -5
drivers/staging/android/ion/ion_cma_heap.c
··· 87 87 .unmap_kernel = ion_heap_unmap_kernel, 88 88 }; 89 89 90 - struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data) 90 + static struct ion_heap *__ion_cma_heap_create(struct cma *cma) 91 91 { 92 92 struct ion_cma_heap *cma_heap; 93 93 ··· 101 101 * get device from private heaps data, later it will be 102 102 * used to make the link with reserved CMA memory 103 103 */ 104 - cma_heap->cma = data->priv; 104 + cma_heap->cma = cma; 105 105 cma_heap->heap.type = ION_HEAP_TYPE_DMA; 106 106 return &cma_heap->heap; 107 107 } 108 108 109 - void ion_cma_heap_destroy(struct ion_heap *heap) 109 + int __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 112 113 - kfree(cma_heap); 113 + heap = __ion_cma_heap_create(cma); 114 + if (IS_ERR(heap)) 115 + return PTR_ERR(heap); 116 + 117 + heap->name = cma_get_name(cma); 118 + 119 + ion_device_add_heap(heap); 120 + return 0; 114 121 } 122 + 123 + static int ion_add_cma_heaps(void) 124 + { 125 + cma_for_each_area(__ion_add_cma_heaps, NULL); 126 + return 0; 127 + } 128 + device_initcall(ion_add_cma_heaps);
-71
drivers/staging/android/ion/ion_heap.c
··· 314 314 heap->shrinker.batch = 0; 315 315 register_shrinker(&heap->shrinker); 316 316 } 317 - 318 - struct 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 - } 357 - EXPORT_SYMBOL(ion_heap_create); 358 - 359 - void 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 - } 387 - EXPORT_SYMBOL(ion_heap_destroy);
+24 -14
drivers/staging/android/ion/ion_system_heap.c
··· 320 320 return -ENOMEM; 321 321 } 322 322 323 - struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused) 323 + static struct ion_heap *__ion_system_heap_create(void) 324 324 { 325 325 struct ion_system_heap *heap; 326 326 ··· 348 348 return ERR_PTR(-ENOMEM); 349 349 } 350 350 351 - void ion_system_heap_destroy(struct ion_heap *heap) 351 + static int ion_system_heap_create(void) 352 352 { 353 - struct ion_system_heap *sys_heap = container_of(heap, 354 - struct ion_system_heap, 355 - heap); 356 - int i; 353 + struct ion_heap *heap; 357 354 358 - for (i = 0; i < NUM_ORDERS; i++) { 359 - ion_page_pool_destroy(sys_heap->uncached_pools[i]); 360 - ion_page_pool_destroy(sys_heap->cached_pools[i]); 361 - } 362 - kfree(sys_heap); 355 + heap = __ion_system_heap_create(); 356 + if (IS_ERR(heap)) 357 + return PTR_ERR(heap); 358 + heap->name = "ion_system_heap"; 359 + 360 + ion_device_add_heap(heap); 361 + return 0; 363 362 } 363 + device_initcall(ion_system_heap_create); 364 364 365 365 static int ion_system_contig_heap_allocate(struct ion_heap *heap, 366 366 struct ion_buffer *buffer, ··· 429 429 .map_user = ion_heap_map_user, 430 430 }; 431 431 432 - struct ion_heap *ion_system_contig_heap_create(struct ion_platform_heap *unused) 432 + static struct ion_heap *__ion_system_contig_heap_create(void) 433 433 { 434 434 struct ion_heap *heap; 435 435 ··· 438 438 return ERR_PTR(-ENOMEM); 439 439 heap->ops = &kmalloc_ops; 440 440 heap->type = ION_HEAP_TYPE_SYSTEM_CONTIG; 441 + heap->name = "ion_system_contig_heap"; 441 442 return heap; 442 443 } 443 444 444 - void ion_system_contig_heap_destroy(struct ion_heap *heap) 445 + static 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 } 456 + device_initcall(ion_system_contig_heap_create); 457 +