From af3b0010cd4c129636a47dbf02a720762b010ca4 Mon Sep 17 00:00:00 2001 From: Jianqun Xu Date: Thu, 4 Feb 2021 15:21:59 +0800 Subject: [PATCH] staging: android: ion: system-heap adjust orders if swiotlb limit This patch is useful for board with totalram size larger than 4GB. Since swiotlb has memory size limitation, this will calculate the maximum size locally, as a workaround to fix the orders[0]. With this patch: [ 3.921612] orders[0] = 6 [ 3.921647] orders[1] = 4 [ 3.921715] orders[2] = 0 Change-Id: I9286f6ea53f679816c9afd378a6cfe620ef1b53e Signed-off-by: Jianqun Xu --- drivers/staging/android/ion/ion_system_heap.c | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 06c3e6c9c7ae..6f73363c2282 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "ion.h" @@ -21,7 +22,7 @@ static gfp_t high_order_gfp_flags = (GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN | __GFP_NORETRY) & ~__GFP_RECLAIM; static gfp_t low_order_gfp_flags = GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN; -static const unsigned int orders[] = {8, 4, 0}; +static unsigned int orders[] = {8, 4, 0}; static int order_to_index(unsigned int order) { @@ -347,6 +348,32 @@ int ion_system_heap_create(void) { struct ion_heap *heap; +#ifdef CONFIG_SWIOTLB + /* + * Since swiotlb has memory size limitation, this will calculate + * the maximum size locally. + * + * Once swiotlb_max_segment() return not '0', means that the totalram size + * is larger than 4GiB and swiotlb is not force mode, in this case, system + * heap should limit largest allocation. + * + * FIX: fix the orders[] as a workaround. + */ + if (swiotlb_max_segment()) { + unsigned int max_size = (1 << IO_TLB_SHIFT) * IO_TLB_SEGSIZE; + int max_order = MAX_ORDER; + int i; + + max_size = max_t(unsigned int, max_size, PAGE_SIZE) >> PAGE_SHIFT; + max_order = min(max_order, ilog2(max_size)); + for (i = 0; i < NUM_ORDERS; i++) { + if (max_order < orders[i]) + orders[i] = max_order; + pr_info("orders[%d] = %u\n", i, orders[i]); + } + } +#endif + heap = __ion_system_heap_create(); if (IS_ERR(heap)) return PTR_ERR(heap);