summaryrefslogtreecommitdiffstats
path: root/drivers/staging/android/ion/ion_system_heap.c
diff options
context:
space:
mode:
authorRebecca Schultz Zavin2013-12-13 23:24:39 +0100
committerGreg Kroah-Hartman2013-12-14 17:55:41 +0100
commitea313b5f88ed7119f79ad3f6b85e9620971b9875 (patch)
tree2d2e68ecab9c1114d013791d2fe49f78d68f6828 /drivers/staging/android/ion/ion_system_heap.c
parentgpu: ion: Fix bug in ion shrinker (diff)
downloadkernel-qcow2-linux-ea313b5f88ed7119f79ad3f6b85e9620971b9875.tar.gz
kernel-qcow2-linux-ea313b5f88ed7119f79ad3f6b85e9620971b9875.tar.xz
kernel-qcow2-linux-ea313b5f88ed7119f79ad3f6b85e9620971b9875.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. Signed-off-by: Rebecca Schultz Zavin <rebecca@android.com> [jstultz: modified patch to apply to staging directory] Signed-off-by: John Stultz <john.stultz@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/android/ion/ion_system_heap.c')
-rw-r--r--drivers/staging/android/ion/ion_system_heap.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 6665797f5370..fedbc0d5fa7d 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/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: