android: ion: add properties to ion_heap_data
authorCho KyongHo <pullip.cho@samsung.com>
Sun, 11 Feb 2018 08:34:49 +0000 (17:34 +0900)
committerSangwook Ju <sw.ju@samsung.com>
Mon, 14 May 2018 10:45:23 +0000 (19:45 +0900)
ion_heap_data is lack of heap properties that is critical to users.
Users may want to know the total size of the cma/carved out memory
pools served by cma heap and carveout heap, respectively. They also
need to know if a heap provides buffer protection for DRM video
streams or allocated buffer from a heap can be accessed.

Change-Id: I3c3a6b9a41d32398ddfe1b1c21b3977e790e5c25
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/staging/android/ion/ion.c
drivers/staging/android/ion/ion.h
drivers/staging/android/ion/ion_carveout_heap.c
drivers/staging/android/ion/ion_cma_heap.c
drivers/staging/android/uapi/ion.h

index 298edb9ffc455bfc99253a0ccd3365d7d27d451e..ec22bccded53de44d9cc1221736f531b39421ec6 100644 (file)
@@ -495,8 +495,6 @@ int ion_query_heaps(struct ion_heap_query *query)
        struct ion_heap *heap;
        struct ion_heap_data hdata;
 
-       memset(&hdata, 0, sizeof(hdata));
-
        down_read(&dev->lock);
        if (!buffer) {
                query->cnt = dev->heap_cnt;
@@ -510,11 +508,19 @@ int ion_query_heaps(struct ion_heap_query *query)
        max_cnt = query->cnt;
 
        plist_for_each_entry(heap, &dev->heaps, node) {
+               memset(&hdata, 0, sizeof(hdata));
+
                strncpy(hdata.name, heap->name, MAX_HEAP_NAME);
                hdata.name[sizeof(hdata.name) - 1] = '\0';
                hdata.type = heap->type;
                hdata.heap_id = heap->id;
 
+               if (heap->flags & ION_HEAP_FLAG_DEFER_FREE)
+                       hdata.heap_flags = ION_HEAPDATA_FLAGS_DEFER_FREE;
+
+               if (heap->ops->query_heap)
+                       heap->ops->query_heap(heap, &hdata);
+
                if (copy_to_user(&buffer[cnt], &hdata, sizeof(hdata))) {
                        ret = -EFAULT;
                        goto out;
index ebbcb80521c6efbbfa75c54d770d0642852c8144..7c4011fc2cfa6957c76efd091cdafe210039bf84 100644 (file)
@@ -113,6 +113,7 @@ struct ion_device {
  * @map_kernel         map memory to the kernel
  * @unmap_kernel       unmap memory to the kernel
  * @map_user           map memory to userspace
+ * @query_heap         specifies heap specific data to ion_heap_data to users
  *
  * allocate, phys, and map_user return 0 on success, -errno on error.
  * map_dma and map_kernel return pointer on success, ERR_PTR on
@@ -120,6 +121,7 @@ struct ion_device {
  * the buffer's private_flags when called from a shrinker. In that
  * case, the pages being free'd must be truly free'd back to the
  * system, not put in a page pool or otherwise cached.
+ * @query_heap is optional.
  */
 struct ion_heap_ops {
        int (*allocate)(struct ion_heap *heap,
@@ -131,6 +133,7 @@ struct ion_heap_ops {
        int (*map_user)(struct ion_heap *mapper, struct ion_buffer *buffer,
                        struct vm_area_struct *vma);
        int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan);
+       void (*query_heap)(struct ion_heap *heap, struct ion_heap_data *data);
 };
 
 /**
index be9d66bab790bbcb13291f78e302a5758ad21501..db4f716e108342391d3ebf9af0472a20e6b3a89f 100644 (file)
@@ -162,12 +162,26 @@ static void *carveout_heap_map_kernel(struct ion_heap *heap,
        return ion_heap_map_kernel(heap, buffer);
 }
 
+static void carveout_heap_query(struct ion_heap *heap,
+                               struct ion_heap_data *data)
+{
+       struct ion_carveout_heap *carveout_heap =
+               container_of(heap, struct ion_carveout_heap, heap);
+
+       data->size = carveout_heap->size;
+       if (carveout_heap->secure)
+               data->heap_flags |= ION_HEAPDATA_FLAGS_ALLOW_PROTECTION;
+       if (carveout_heap->untouchable)
+               data->heap_flags |= ION_HEAPDATA_FLAGS_UNTOUCHABLE;
+}
+
 static struct ion_heap_ops carveout_heap_ops = {
        .allocate = ion_carveout_heap_allocate,
        .free = ion_carveout_heap_free,
        .map_user = carveout_heap_map_user,
        .map_kernel = carveout_heap_map_kernel,
        .unmap_kernel = ion_heap_unmap_kernel,
+       .query_heap = carveout_heap_query,
 };
 
 struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *heap_data)
index 8b9e3a474be5ab16b4e596e684a35e7d65957eb1..ae246c6ec680410ae4aea0e32d255db488556316 100644 (file)
@@ -130,12 +130,22 @@ static void ion_cma_free(struct ion_buffer *buffer)
        kfree(buffer->sg_table);
 }
 
+static void cma_heap_query(struct ion_heap *heap, struct ion_heap_data *data)
+{
+       struct ion_cma_heap *cma_heap = to_cma_heap(heap);
+
+       data->size = (u32)cma_get_size(cma_heap->cma);
+       if (cma_heap->secure)
+               data->heap_flags |= ION_HEAPDATA_FLAGS_ALLOW_PROTECTION;
+}
+
 static struct ion_heap_ops ion_cma_ops = {
        .allocate = ion_cma_allocate,
        .free = ion_cma_free,
        .map_user = ion_heap_map_user,
        .map_kernel = ion_heap_map_kernel,
        .unmap_kernel = ion_heap_unmap_kernel,
+       .query_heap = cma_heap_query,
 };
 
 #ifdef CONFIG_ION_EXYNOS
index a009dec8ef8d21421a3baaa9153a4b72f876c08f..d480b4f754b9e629ccdd212a2cfa11d35403ac33 100644 (file)
@@ -105,18 +105,34 @@ struct ion_allocation_data {
 
 #define MAX_HEAP_NAME                  32
 
+/**
+ * freed buffer to the heap may not be returned to the free pool immediately
+ */
+#define ION_HEAPDATA_FLAGS_DEFER_FREE          1
+/**
+ * ION_FLAG_PROTECTED is applicable.
+ */
+#define ION_HEAPDATA_FLAGS_ALLOW_PROTECTION    2
+/**
+ * access to the buffer from this heap is not allowed in both of userland and
+ * kernel space. mmap() and dmabuf kmap/vmap always fail.
+ */
+#define ION_HEAPDATA_FLAGS_UNTOUCHABLE         4
 /**
  * struct ion_heap_data - data about a heap
  * @name - first 32 characters of the heap name
  * @type - heap type
  * @heap_id - heap id for the heap
+ * @size - size of the memory pool if the heap type is dma, carveout and chunk
+ * @heap_flags - properties of heap
+ *
  */
 struct ion_heap_data {
        char name[MAX_HEAP_NAME];
        __u32 type;
        __u32 heap_id;
-       __u32 reserved0;
-       __u32 reserved1;
+       __u32 size;       /* reserved0 */
+       __u32 heap_flags; /* reserved1 */
        __u32 reserved2;
 };