From 3ec876befebf7c7bffeaf63ff8679525cc800259 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Thu, 22 Feb 2018 20:55:24 +0900 Subject: [PATCH] android: ion: add kernel log on errors It is very important to know the reason of an exception. It is too difficult to know the details about the exception with an error number returned by ION. Change-Id: I51f92bb1cc1c1eee2e0a1a17803d4f5bb0720433 Signed-off-by: Cho KyongHo --- drivers/staging/android/ion/ion-ioctl.c | 25 ++++++++++++++-- drivers/staging/android/ion/ion.c | 30 +++++++++++++++---- .../staging/android/ion/ion_buffer_protect.c | 2 ++ .../staging/android/ion/ion_carveout_heap.c | 15 ++++++++-- drivers/staging/android/ion/ion_cma_heap.c | 4 ++- drivers/staging/android/ion/ion_heap.c | 4 ++- drivers/staging/android/ion/ion_page_pool.c | 6 +++- drivers/staging/android/ion/ion_system_heap.c | 8 +++-- 8 files changed, 78 insertions(+), 16 deletions(-) diff --git a/drivers/staging/android/ion/ion-ioctl.c b/drivers/staging/android/ion/ion-ioctl.c index 021a956db1a8..52063f91df05 100644 --- a/drivers/staging/android/ion/ion-ioctl.c +++ b/drivers/staging/android/ion/ion-ioctl.c @@ -20,6 +20,17 @@ #include "ion.h" +/* + * ION_IOC_FREE and ion_handle_data is deprecated from ION after 4.14. + * But it is used to study the version of ION by libion in Android. + * Therefore, ion_ioctl() should not blaim if a user send ION_IOC_FREE. + */ +struct ion_handle_data { + int handle; +}; + +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + union ion_ioctl_arg { struct ion_allocation_data allocation; struct ion_heap_query query; @@ -39,7 +50,13 @@ static int validate_ioctl_arg(unsigned int cmd, union ion_ioctl_arg *arg) break; } - return ret ? -EINVAL : 0; + if (ret) { + pr_err("%s: reserved fields of query_data should be 0\n", + __func__); + return -EINVAL; + } + + return 0; } /* fix up the cases where the ioctl direction bits are incorrect */ @@ -59,8 +76,10 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) dir = ion_ioctl_dir(cmd); - if (_IOC_SIZE(cmd) > sizeof(data)) + if (_IOC_SIZE(cmd) > sizeof(data)) { + pr_err("%s: unknown ioctl %#x\n", __func__, cmd); return -EINVAL; + } /* * The copy_from_user is unconditional here for both read and write @@ -98,6 +117,8 @@ long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = ion_query_heaps(&data.query); break; default: + if (cmd != ION_IOC_FREE) + pr_err("%s: unknown ioctl %#x\n", __func__, cmd); return -ENOTTY; } diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 6f71a00715fa..b726485f5cc3 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -127,6 +127,8 @@ err1: heap->ops->free(buffer); err2: kfree(buffer); + pr_err("%s: failed to alloc (len %zu, flag %#lx) buffer from %s heap\n", + __func__, len, flags, heap->name); return ERR_PTR(ret); } @@ -166,8 +168,11 @@ static void *ion_buffer_kmap_get(struct ion_buffer *buffer) if (WARN_ONCE(!vaddr, "heap->ops->map_kernel should return ERR_PTR on error")) return ERR_PTR(-EINVAL); - if (IS_ERR(vaddr)) + if (IS_ERR(vaddr)) { + pr_err("%s: failed to alloc kernel address of %zu buffer\n", + __func__, buffer->size); return vaddr; + } buffer->vaddr = vaddr; buffer->kmap_cnt++; return vaddr; @@ -440,8 +445,11 @@ struct dma_buf *__ion_alloc(size_t len, unsigned int heap_id_mask, */ len = PAGE_ALIGN(len); - if (!len) + if (!len) { + pr_err("%s: zero size allocation - heapmask %#x, flags %#x\n", + __func__, heap_id_mask, flags); return ERR_PTR(-EINVAL); + } down_read(&dev->lock); plist_for_each_entry(heap, &dev->heaps, node) { @@ -454,8 +462,11 @@ struct dma_buf *__ion_alloc(size_t len, unsigned int heap_id_mask, } up_read(&dev->lock); - if (!buffer) + if (!buffer) { + pr_err("%s: no matching heap found against heapmaks %#x\n", + __func__, heap_id_mask); return ERR_PTR(-ENODEV); + } if (IS_ERR(buffer)) return ERR_CAST(buffer); @@ -466,8 +477,11 @@ struct dma_buf *__ion_alloc(size_t len, unsigned int heap_id_mask, exp_info.priv = buffer; dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(dmabuf)) + if (IS_ERR(dmabuf)) { + pr_err("%s: failed to export dmabuf (err %ld)\n", __func__, + -PTR_ERR(dmabuf)); _ion_buffer_destroy(buffer); + } return dmabuf; } @@ -481,8 +495,10 @@ int ion_alloc(size_t len, unsigned int heap_id_mask, unsigned int flags) return PTR_ERR(dmabuf); fd = dma_buf_fd(dmabuf, O_CLOEXEC); - if (fd < 0) + if (fd < 0) { + pr_err("%s: failed to get dmabuf fd (err %d)\n", __func__, -fd); dma_buf_put(dmabuf); + } return fd; } @@ -502,8 +518,10 @@ int ion_query_heaps(struct ion_heap_query *query) goto out; } - if (query->cnt <= 0) + if (query->cnt <= 0) { + pr_err("%s: invalid heapdata count %u\n", __func__, query->cnt); goto out; + } max_cnt = query->cnt; diff --git a/drivers/staging/android/ion/ion_buffer_protect.c b/drivers/staging/android/ion/ion_buffer_protect.c index 30bce3f10a3a..5b6363765177 100644 --- a/drivers/staging/android/ion/ion_buffer_protect.c +++ b/drivers/staging/android/ion/ion_buffer_protect.c @@ -180,6 +180,8 @@ void *ion_buffer_protect_single(unsigned int protection_id, unsigned int size, ret = ion_secure_protect(protdesc, protalign); if (ret) { + pr_err("%s: protection failure (id%u,len%u,base%#lx,align%#x\n", + __func__, protection_id, size, phys, protalign); kfree(protdesc); return ERR_PTR(ret); } diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index db4f716e1083..8182f037ceb2 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -83,11 +83,16 @@ static int ion_carveout_heap_allocate(struct ion_heap *heap, if (!table) return -ENOMEM; ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) + if (ret) { + pr_err("%s: failed to allocate scatterlist (err %d)\n", + __func__, ret); goto err_free; + } paddr = ion_carveout_allocate(carveout_heap, aligned_size); if (paddr == ION_CARVEOUT_ALLOCATE_FAIL) { + pr_err("%s: failed to allocate from %s(id %d), size %lu\n", + __func__, heap->name, heap->id, size); ret = -ENOMEM; goto err_free_table; } @@ -144,8 +149,10 @@ static int carveout_heap_map_user(struct ion_heap *heap, struct ion_carveout_heap *carveout_heap = container_of(heap, struct ion_carveout_heap, heap); - if (carveout_heap->untouchable) + if (carveout_heap->untouchable) { + pr_err("%s: mmap of %s heap unallowed\n", __func__, heap->name); return -EACCES; + } return ion_heap_map_user(heap, buffer, vma); } @@ -156,8 +163,10 @@ static void *carveout_heap_map_kernel(struct ion_heap *heap, struct ion_carveout_heap *carveout_heap = container_of(heap, struct ion_carveout_heap, heap); - if (carveout_heap->untouchable) + if (carveout_heap->untouchable) { + pr_err("%s: mapping %s heap unallowed\n", __func__, heap->name); return ERR_PTR(-EACCES); + } return ion_heap_map_kernel(heap, buffer); } diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c index ae246c6ec680..82361db6fe66 100644 --- a/drivers/staging/android/ion/ion_cma_heap.c +++ b/drivers/staging/android/ion/ion_cma_heap.c @@ -84,8 +84,10 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer, goto err; ret = sg_alloc_table(table, 1, GFP_KERNEL); - if (ret) + if (ret) { + pr_err("%s: failed to alloc sgtable(err %d)\n", __func__, -ret); goto free_mem; + } sg_set_page(table->sgl, pages, size, 0); diff --git a/drivers/staging/android/ion/ion_heap.c b/drivers/staging/android/ion/ion_heap.c index 91faa7f035b9..1f73ad7bef1a 100644 --- a/drivers/staging/android/ion/ion_heap.c +++ b/drivers/staging/android/ion/ion_heap.c @@ -56,8 +56,10 @@ void *ion_heap_map_kernel(struct ion_heap *heap, vaddr = vmap(pages, npages, VM_MAP, pgprot); vfree(pages); - if (!vaddr) + if (!vaddr) { + pr_err("%s: failed vmap %d pages\n", __func__, npages); return ERR_PTR(-ENOMEM); + } return vaddr; } diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 98df137319c0..52d9d53bf85c 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -36,8 +36,12 @@ static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool, bool nozero) gfpmask &= ~__GFP_ZERO; page = alloc_pages(gfpmask, pool->order); - if (!page) + if (!page) { + if (pool->order == 0) + pr_err("%s: failed to alloc order-0 page (gfp %pGg)\n", + __func__, &gfpmask); return NULL; + } return page; } diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index b5c3bce9feb3..7caad6ee5fc6 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -140,8 +140,10 @@ static int ion_system_heap_allocate(struct ion_heap *heap, unsigned long size_remaining = PAGE_ALIGN(size); unsigned int max_order = orders[0]; - if (size / PAGE_SIZE > totalram_pages / 2) + if (size / PAGE_SIZE > totalram_pages / 2) { + pr_err("%s: too large allocation, %zu bytes\n", __func__, size); return -ENOMEM; + } INIT_LIST_HEAD(&pages); while (size_remaining > 0) { @@ -158,8 +160,10 @@ static int ion_system_heap_allocate(struct ion_heap *heap, if (!table) goto free_pages; - if (sg_alloc_table(table, i, GFP_KERNEL)) + if (sg_alloc_table(table, i, GFP_KERNEL)) { + pr_err("%s: failed to alloc sgtable of %d nent\n", __func__, i); goto free_table; + } sg = table->sgl; list_for_each_entry_safe(page, tmp_page, &pages, lru) { -- 2.20.1