summaryrefslogtreecommitdiff
path: root/drivers/gpu/ion/ion_system_heap.c
diff options
context:
space:
mode:
authorRebecca Schultz Zavin <rebecca@android.com>2013-05-23 13:37:25 -0700
committerArve Hjønnevåg <arve@android.com>2013-07-01 14:16:26 -0700
commitc1c5c05ce6cc0f1a8cb21406b73de0ba649a2c34 (patch)
treefccfbf0280fdad128d67c6e97615b41caa7b5b64 /drivers/gpu/ion/ion_system_heap.c
parent760017d10ac80defe7fa9ad12aebf36ced5f3119 (diff)
downloadolio-linux-3.10-c1c5c05ce6cc0f1a8cb21406b73de0ba649a2c34.tar.xz
olio-linux-3.10-c1c5c05ce6cc0f1a8cb21406b73de0ba649a2c34.zip
gpu: ion: Also shrink memory cached in the deferred free list
When the system is low on memory, we want to shrink any cached system memory ion is holding. Previously we were shrinking memory in the page pools, but not in the deferred free list. This patch makes it possible to shrink both. It also moves the shrinker code into the heaps so they can correctly manage any caches they might contain. Change-Id: I177f587f999a5220eddbf7af94745aae736cac75 Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com>
Diffstat (limited to 'drivers/gpu/ion/ion_system_heap.c')
-rw-r--r--drivers/gpu/ion/ion_system_heap.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 6369fe8f305..37e1871ee02 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -253,6 +253,50 @@ static struct ion_heap_ops system_heap_ops = {
.map_user = ion_heap_map_user,
};
+static int ion_system_heap_shrink(struct shrinker *shrinker,
+ struct shrink_control *sc) {
+
+ struct ion_heap *heap = container_of(shrinker, struct ion_heap,
+ shrinker);
+ struct ion_system_heap *sys_heap = container_of(heap,
+ struct ion_system_heap,
+ heap);
+ int nr_total = 0;
+ int nr_freed = 0;
+ int i;
+
+ if (sc->nr_to_scan == 0)
+ goto end;
+
+ /* shrink the free list first, no point in zeroing the memory if
+ we're just going to reclaim it */
+ nr_freed += ion_heap_freelist_drain(heap, sc->nr_to_scan * PAGE_SIZE) /
+ PAGE_SIZE;
+
+ if (nr_freed >= sc->nr_to_scan)
+ goto end;
+
+ for (i = 0; i < num_orders; i++) {
+ struct ion_page_pool *pool = sys_heap->pools[i];
+
+ nr_freed += ion_page_pool_shrink(pool, sc->gfp_mask,
+ sc->nr_to_scan);
+ if (nr_freed >= sc->nr_to_scan)
+ break;
+ }
+
+end:
+ /* total number of items is whatever the page pools are holding
+ plus whatever's in the freelist */
+ for (i = 0; i < num_orders; i++) {
+ struct ion_page_pool *pool = sys_heap->pools[i];
+ nr_total += ion_page_pool_shrink(pool, sc->gfp_mask, 0);
+ }
+ nr_total += ion_heap_freelist_size(heap) / PAGE_SIZE;
+ return nr_total;
+
+}
+
static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
void *unused)
{
@@ -299,6 +343,11 @@ struct ion_heap *ion_system_heap_create(struct ion_platform_heap *unused)
goto err_create_pool;
heap->pools[i] = pool;
}
+
+ heap->heap.shrinker.shrink = ion_system_heap_shrink;
+ heap->heap.shrinker.seeks = DEFAULT_SEEKS;
+ heap->heap.shrinker.batch = 0;
+ register_shrinker(&heap->heap.shrinker);
heap->heap.debug_show = ion_system_heap_debug_show;
return &heap->heap;
err_create_pool: