lkml.org 
[lkml]   [2018]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL for 4.14 031/110] staging: ion: Fix ion_cma_heap allocations
    Date
    From: John Stultz <john.stultz@linaro.org>

    [ Upstream commit f292b9b28097d8fe870336108e91bd95a14294bf ]

    In trying to add support for drm_hwcomposer to HiKey,
    I've needed to utilize the ION CMA heap, and I've noticed
    problems with allocations on newer kernels failing.

    It seems back with 204f672255c2 ("ion: Use CMA APIs directly"),
    the ion_cma_heap code was modified to use the CMA API, but
    kept the arguments as buffer lengths rather then number of pages.

    This results in errors as we don't have enough pages in CMA to
    satisfy the exaggerated requests.

    This patch converts the ion_cma_heap CMA API usage to properly
    request pages.

    It also fixes a minor issue in the allocation where in the error
    path, the cma_release is called with the buffer->size value which
    hasn't yet been set.

    Cc: Laura Abbott <labbott@redhat.com>
    Cc: Sumit Semwal <sumit.semwal@linaro.org>
    Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
    Cc: Archit Taneja <architt@codeaurora.org>
    Cc: Greg KH <gregkh@linuxfoundation.org>
    Cc: Daniel Vetter <daniel@ffwll.ch>
    Cc: Dmitry Shmidt <dimitrysh@google.com>
    Cc: Todd Kjos <tkjos@google.com>
    Cc: Amit Pundir <amit.pundir@linaro.org>
    Fixes: 204f672255c2 ("staging: android: ion: Use CMA APIs directly")
    Acked-by: Laura Abbott <labbott@redhat.com>
    Signed-off-by: John Stultz <john.stultz@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    ---
    drivers/staging/android/ion/Kconfig | 2 +-
    drivers/staging/android/ion/ion_cma_heap.c | 15 +++++++++++----
    2 files changed, 12 insertions(+), 5 deletions(-)

    diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
    index a517b2d29f1b..8f6494158d3d 100644
    --- a/drivers/staging/android/ion/Kconfig
    +++ b/drivers/staging/android/ion/Kconfig
    @@ -37,7 +37,7 @@ config ION_CHUNK_HEAP

    config ION_CMA_HEAP
    bool "Ion CMA heap support"
    - depends on ION && CMA
    + depends on ION && DMA_CMA
    help
    Choose this option to enable CMA heaps with Ion. This heap is backed
    by the Contiguous Memory Allocator (CMA). If your system has these
    diff --git a/drivers/staging/android/ion/ion_cma_heap.c b/drivers/staging/android/ion/ion_cma_heap.c
    index dd5545d9990a..86196ffd2faf 100644
    --- a/drivers/staging/android/ion/ion_cma_heap.c
    +++ b/drivers/staging/android/ion/ion_cma_heap.c
    @@ -39,9 +39,15 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
    struct ion_cma_heap *cma_heap = to_cma_heap(heap);
    struct sg_table *table;
    struct page *pages;
    + unsigned long size = PAGE_ALIGN(len);
    + unsigned long nr_pages = size >> PAGE_SHIFT;
    + unsigned long align = get_order(size);
    int ret;

    - pages = cma_alloc(cma_heap->cma, len, 0, GFP_KERNEL);
    + if (align > CONFIG_CMA_ALIGNMENT)
    + align = CONFIG_CMA_ALIGNMENT;
    +
    + pages = cma_alloc(cma_heap->cma, nr_pages, align, GFP_KERNEL);
    if (!pages)
    return -ENOMEM;

    @@ -53,7 +59,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
    if (ret)
    goto free_mem;

    - sg_set_page(table->sgl, pages, len, 0);
    + sg_set_page(table->sgl, pages, size, 0);

    buffer->priv_virt = pages;
    buffer->sg_table = table;
    @@ -62,7 +68,7 @@ static int ion_cma_allocate(struct ion_heap *heap, struct ion_buffer *buffer,
    free_mem:
    kfree(table);
    err:
    - cma_release(cma_heap->cma, pages, buffer->size);
    + cma_release(cma_heap->cma, pages, nr_pages);
    return -ENOMEM;
    }

    @@ -70,9 +76,10 @@ static void ion_cma_free(struct ion_buffer *buffer)
    {
    struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap);
    struct page *pages = buffer->priv_virt;
    + unsigned long nr_pages = PAGE_ALIGN(buffer->size) >> PAGE_SHIFT;

    /* release memory */
    - cma_release(cma_heap->cma, pages, buffer->size);
    + cma_release(cma_heap->cma, pages, nr_pages);
    /* release sg table */
    sg_free_table(buffer->sg_table);
    kfree(buffer->sg_table);
    --
    2.11.0
    \
     
     \ /
      Last update: 2018-02-03 19:06    [W:2.254 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site