From 4eddc1b416a07b4479eb4d13f97824b02152a881 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Mon, 7 Oct 2019 16:26:33 -0700 Subject: [PATCH] ion: msm: Add support for ION heaps to implement prefetch and drain Allow the ION heaps to implement the prefetch and drain operations. This allows clients to prefetch memory to be able to reserve memory for fast ION allocations at a later point in time, as well as unreserve the memory. Change-Id: I144a4bc45b8b4f28974734d2aa37692db8e169a1 Signed-off-by: Isaac J. Manjarres --- .../android/ion/heaps/ion_system_heap.c | 6 +- drivers/staging/android/ion/heaps/msm_ion.c | 65 +++++++++++++++++-- .../staging/android/ion/heaps/msm_ion_priv.h | 33 ++++++++-- include/linux/msm_ion.h | 25 +++++++ 4 files changed, 115 insertions(+), 14 deletions(-) diff --git a/drivers/staging/android/ion/heaps/ion_system_heap.c b/drivers/staging/android/ion/heaps/ion_system_heap.c index 699ddd204030..2c5ab98caacd 100644 --- a/drivers/staging/android/ion/heaps/ion_system_heap.c +++ b/drivers/staging/android/ion/heaps/ion_system_heap.c @@ -605,6 +605,10 @@ static int ion_system_heap_debug_show(struct ion_heap *heap, return 0; } +static struct msm_ion_heap_ops msm_system_heap_ops = { + .debug_show = ion_system_heap_debug_show, +}; + static void ion_system_heap_destroy_pools(struct ion_page_pool **pools) { int i; @@ -710,7 +714,7 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *data) if (!heap) return ERR_PTR(-ENOMEM); heap->heap.dev = data->priv; - heap->heap.debug_show = ion_system_heap_debug_show; + heap->heap.msm_heap_ops = &msm_system_heap_ops; heap->heap.ion_heap.ops = &system_heap_ops; heap->heap.ion_heap.buf_ops = msm_ion_dma_buf_ops; heap->heap.ion_heap.type = ION_HEAP_TYPE_SYSTEM; diff --git a/drivers/staging/android/ion/heaps/msm_ion.c b/drivers/staging/android/ion/heaps/msm_ion.c index 73451c032e1e..c52229cebe0b 100644 --- a/drivers/staging/android/ion/heaps/msm_ion.c +++ b/drivers/staging/android/ion/heaps/msm_ion.c @@ -101,8 +101,10 @@ static int msm_ion_debug_heap_show(struct seq_file *s, void *unused) { struct msm_ion_heap *msm_heap = s->private; - if (msm_heap && msm_heap->debug_show) - msm_heap->debug_show(&msm_heap->ion_heap, s, unused); + if (msm_heap && msm_heap->msm_heap_ops && + msm_heap->msm_heap_ops->debug_show) + msm_heap->msm_heap_ops->debug_show(&msm_heap->ion_heap, s, + unused); return 0; } @@ -125,7 +127,8 @@ static void msm_ion_debugfs_create_file(struct msm_ion_heap *msm_heap) struct dentry *debugfs_root; struct ion_heap *heap; - if (msm_heap && msm_heap->debug_show && + if (msm_heap && msm_heap->msm_heap_ops && + msm_heap->msm_heap_ops->debug_show && msm_heap->ion_heap.debugfs_dir) { heap = &msm_heap->ion_heap; debugfs_root = heap->debugfs_dir; @@ -198,7 +201,7 @@ struct device *msm_ion_heap_device(struct ion_heap *heap) return to_msm_ion_heap(heap)->dev; } -struct device *msm_ion_heap_device_by_id(int heap_id) +static struct ion_heap *ion_heap_by_id(int heap_id) { struct ion_heap *heap; @@ -208,13 +211,61 @@ struct device *msm_ion_heap_device_by_id(int heap_id) return ERR_PTR(-ENODEV); heap = get_ion_heap(heap_id); - if (heap) - return msm_ion_heap_device(heap); + if (!heap) + return ERR_PTR(-EINVAL); + return heap; +} - return ERR_PTR(-EINVAL); +struct device *msm_ion_heap_device_by_id(int heap_id) +{ + struct ion_heap *heap; + + heap = ion_heap_by_id(heap_id); + if (IS_ERR(heap)) + return ERR_CAST(heap); + + return to_msm_ion_heap(heap)->dev; } EXPORT_SYMBOL(msm_ion_heap_device_by_id); +int msm_ion_heap_prefetch(int heap_id, struct ion_prefetch_region *regions, + int nr_regions) +{ + struct ion_heap *heap = ion_heap_by_id(heap_id); + struct msm_ion_heap *msm_heap; + + if (IS_ERR(heap)) + return PTR_ERR(heap); + + msm_heap = to_msm_ion_heap(heap); + + if (msm_heap->msm_heap_ops && msm_heap->msm_heap_ops->heap_prefetch) + return msm_heap->msm_heap_ops->heap_prefetch(heap, regions, + nr_regions); + + return -ENOTSUPP; +} +EXPORT_SYMBOL(msm_ion_heap_prefetch); + +int msm_ion_heap_drain(int heap_id, struct ion_prefetch_region *regions, + int nr_regions) +{ + struct ion_heap *heap = ion_heap_by_id(heap_id); + struct msm_ion_heap *msm_heap; + + if (IS_ERR(heap)) + return PTR_ERR(heap); + + msm_heap = to_msm_ion_heap(heap); + + if (msm_heap->msm_heap_ops && msm_heap->msm_heap_ops->heap_drain) + return msm_heap->msm_heap_ops->heap_drain(heap, regions, + nr_regions); + + return -ENOTSUPP; +} +EXPORT_SYMBOL(msm_ion_heap_drain); + static int msm_ion_get_heap_type_from_dt_node(struct device_node *node, int *heap_type) { diff --git a/drivers/staging/android/ion/heaps/msm_ion_priv.h b/drivers/staging/android/ion/heaps/msm_ion_priv.h index 623329b7aef7..c4498c407bca 100644 --- a/drivers/staging/android/ion/heaps/msm_ion_priv.h +++ b/drivers/staging/android/ion/heaps/msm_ion_priv.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -77,19 +78,39 @@ struct ion_platform_heap { void *priv; }; +/** + * struct msm_ion_heap_ops - defines a set of ops that are specific to the MSM + * ION heaps. + * @heap_prefetch: called to asynchronously prefetch a certain amount of + * memory for allocations from the heap. + * @heap_drain: called to asynchronously drain a certain amount of + * memory that was prefetched for the heap at an earlier + * point in time. + * @debug_show: called when the heap debug file is read to add any heap + * specific debug info to output + */ +struct msm_ion_heap_ops { + int (*heap_prefetch)(struct ion_heap *heap, + struct ion_prefetch_region *regions, + int nr_regions); + int (*heap_drain)(struct ion_heap *heap, + struct ion_prefetch_region *regions, + int nr_regions); + int (*debug_show)(struct ion_heap *heap, struct seq_file *s, + void *unused); +}; + /** * struct msm_ion_heap - defines an ion heap, as well as additional information * relevant to the heap. - * @dev: the device structure associated with the heap - * @debug_show: called when the heap debug file is read to add any heap specific - * debug info to output - * @ion_heap: ion heap + * @dev: the device structure associated with the heap + * @msm_heap_ops: the MSM ION specific heap ops for the heap + * @ion_heap: ion heap * */ struct msm_ion_heap { struct device *dev; - int (*debug_show)(struct ion_heap *heap, struct seq_file *s, - void *unused); + struct msm_ion_heap_ops *msm_heap_ops; struct ion_heap ion_heap; }; diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h index b3233c394909..44340d9c8f3b 100644 --- a/include/linux/msm_ion.h +++ b/include/linux/msm_ion.h @@ -10,6 +10,11 @@ #include #include +struct ion_prefetch_region { + u64 size; + u32 vmid; +}; + #if IS_ENABLED(CONFIG_ION_MSM_HEAPS) struct device *msm_ion_heap_device_by_id(int heap_id); @@ -24,6 +29,12 @@ static inline unsigned int ion_get_flags_num_vm_elems(unsigned int flags) int ion_populate_vm_list(unsigned long flags, unsigned int *vm_list, int nelems); +int msm_ion_heap_prefetch(int heap_id, struct ion_prefetch_region *regions, + int nr_regions); + +int msm_ion_heap_drain(int heap_id, struct ion_prefetch_region *regions, + int nr_regions); + #else static inline struct device *msm_ion_heap_device_by_id(int heap_id) @@ -42,5 +53,19 @@ static inline int ion_populate_vm_list(unsigned long flags, return -EINVAL; } +static inline int msm_ion_heap_prefetch(int heap_id, + struct ion_prefetch_region *regions, + int nr_regions) +{ + return -ENODEV; +} + +static inline int msm_ion_heap_drain(int heap_id, + struct ion_prefetch_region *regions, + int nr_regions) +{ + return -ENODEV; +} + #endif /* CONFIG_ION_MSM_HEAPS */ #endif /* _MSM_ION_H */