diff options
author | Gioh Kim <gioh.kim@lge.com> | 2015-07-06 15:14:40 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-07-14 22:47:30 -0700 |
commit | b44d9ce3b81715311198f0c5fa329e518b4f9f18 (patch) | |
tree | a56a44c4c88b754dd66f067d2465ce6d49da116f /drivers/staging/android | |
parent | 3e3148c51190d680b7cc2ebdc556e6ea27a93989 (diff) | |
download | linux-b44d9ce3b81715311198f0c5fa329e518b4f9f18.tar.bz2 |
staging: ion: shrink page-pool by page unit
This patch shrink page-pool by page unit.
The system shrinker calls ion_heap_shrink_count() to get nr_to_scan,
and pass it to ion_heap_shrink_scan().
The problem is the return value of ion_heap_shrink_count() is the number
of pages but ion_system_heap_shrink(), which is called by
ion_heap_shrink_scan(), gets the number of chunk.
The main root of this is that ion_page_pool_shrink() returns page count
via ion_page_pool_total() if it have to check pool size. But it frees
chunks of pages if it have to free pools.
This patch first fix ion_page_pool_shrink() to count only pages,
not chunks. And then ion_system_heap_shrink() to work on pages.
Signed-off-by: Gioh Kim <gioh.kim@lge.com>
Reviewed-by: Laura Abbott <labbott@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/android')
-rw-r--r-- | drivers/staging/android/ion/ion_page_pool.c | 5 | ||||
-rw-r--r-- | drivers/staging/android/ion/ion_system_heap.c | 16 |
2 files changed, 17 insertions, 4 deletions
diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 4b88f11e52d3..19ad3aba499a 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -116,7 +116,7 @@ static int ion_page_pool_total(struct ion_page_pool *pool, bool high) int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, int nr_to_scan) { - int freed; + int freed = 0; bool high; if (current_is_kswapd()) @@ -127,7 +127,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, if (nr_to_scan == 0) return ion_page_pool_total(pool, high); - for (freed = 0; freed < nr_to_scan; freed++) { + while (freed < nr_to_scan) { struct page *page; mutex_lock(&pool->mutex); @@ -141,6 +141,7 @@ int ion_page_pool_shrink(struct ion_page_pool *pool, gfp_t gfp_mask, } mutex_unlock(&pool->mutex); ion_page_pool_free_pages(pool, page); + freed += (1 << pool->order); } return freed; diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index da2a63c0a9ba..7a7a9a047230 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -212,14 +212,26 @@ static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, { struct ion_system_heap *sys_heap; int nr_total = 0; - int i; + int i, nr_freed; + int only_scan = 0; sys_heap = container_of(heap, struct ion_system_heap, heap); + if (!nr_to_scan) + only_scan = 1; + for (i = 0; i < num_orders; i++) { struct ion_page_pool *pool = sys_heap->pools[i]; - nr_total += ion_page_pool_shrink(pool, gfp_mask, nr_to_scan); + nr_freed = ion_page_pool_shrink(pool, gfp_mask, nr_to_scan); + nr_total += nr_freed; + + if (!only_scan) { + nr_to_scan -= nr_freed; + /* shrink completed */ + if (nr_to_scan <= 0) + break; + } } return nr_total; |