From patchwork Fri Dec 13 22:24:15 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 22406 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pb0-f72.google.com (mail-pb0-f72.google.com [209.85.160.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0628523FBA for ; Fri, 13 Dec 2013 22:27:15 +0000 (UTC) Received: by mail-pb0-f72.google.com with SMTP id jt11sf7442988pbb.7 for ; Fri, 13 Dec 2013 14:27:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=SL7q44tq5J5EGBK+MFOboLQtlUesRzRHVCAcepsuSQM=; b=jOwFr1O29aCjqUyUSgN6hdJqzJ1KopQ1ST1hALlCXsHocx84D0+H7U0VPSpSy0ps8w NQePGU8+2bVy72z7JcNSTenuyEnCU/LMlHSranua3E+J6uli/8VbFGORxj6war36TOza oWEQWoHVbxIowan7/q/hDXdOPK52ZSFIJCJnVnWd98JBFSQ52EErRzkWIgoR+u+gye5e J3P6SUPTgsyX12y9VPDvCmlI10dPB+SW0lbaBmAwFYYcc5+yor6uyjxhEVhqDhRsYq7j CxTLlcHUJ2ozfnag0MiMhxy1wsGhW62Nov28EnACAsCc9VtQs14knZKTt+awt+yuBPd+ yOHQ== X-Gm-Message-State: ALoCoQncmIdHBMcsCRdh7O8WNpslEg8vDeSnJpvJTjVDK2A7vQATlID9bQgmPLn8DnAL3W8xaisx X-Received: by 10.66.190.197 with SMTP id gs5mr2855734pac.14.1386973635272; Fri, 13 Dec 2013 14:27:15 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.116.42 with SMTP id jt10ls1103472qeb.66.gmail; Fri, 13 Dec 2013 14:27:15 -0800 (PST) X-Received: by 10.58.252.167 with SMTP id zt7mr1786090vec.60.1386973635085; Fri, 13 Dec 2013 14:27:15 -0800 (PST) Received: from mail-vb0-f45.google.com (mail-vb0-f45.google.com [209.85.212.45]) by mx.google.com with ESMTPS id vq3si1188231veb.141.2013.12.13.14.27.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 13 Dec 2013 14:27:15 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.45 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.212.45; Received: by mail-vb0-f45.google.com with SMTP id i12so1724206vbh.18 for ; Fri, 13 Dec 2013 14:27:15 -0800 (PST) X-Received: by 10.221.23.72 with SMTP id qz8mr1108149vcb.66.1386973635003; Fri, 13 Dec 2013 14:27:15 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.220.174.196 with SMTP id u4csp73523vcz; Fri, 13 Dec 2013 14:27:14 -0800 (PST) X-Received: by 10.68.245.200 with SMTP id xq8mr5981733pbc.21.1386973633989; Fri, 13 Dec 2013 14:27:13 -0800 (PST) Received: from mail-pa0-f47.google.com (mail-pa0-f47.google.com [209.85.220.47]) by mx.google.com with ESMTPS id im7si2518873pbd.71.2013.12.13.14.27.13 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 13 Dec 2013 14:27:13 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.47 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=209.85.220.47; Received: by mail-pa0-f47.google.com with SMTP id kq14so595505pab.34 for ; Fri, 13 Dec 2013 14:27:13 -0800 (PST) X-Received: by 10.66.216.193 with SMTP id os1mr6135681pac.29.1386973633584; Fri, 13 Dec 2013 14:27:13 -0800 (PST) Received: from localhost.localdomain (c-67-170-153-23.hsd1.or.comcast.net. [67.170.153.23]) by mx.google.com with ESMTPSA id qz9sm7457908pbc.3.2013.12.13.14.27.12 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 13 Dec 2013 14:27:13 -0800 (PST) From: John Stultz To: LKML Cc: Greg KH , Android Kernel Team , Sumit Semwal , Jesse Barker , Colin Cross , Rebecca Schultz Zavin , John Stultz Subject: [PATCH 041/115] gpu: ion: Switch to using a single shrink function Date: Fri, 13 Dec 2013 14:24:15 -0800 Message-Id: <1386973529-4884-42-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1386973529-4884-1-git-send-email-john.stultz@linaro.org> References: <1386973529-4884-1-git-send-email-john.stultz@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: john.stultz@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.45 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Rebecca Schultz Zavin The single shrink function will free lower order pages first. This enables compaction to work properly. [jstultz: modified patch to apply to staging directory] Signed-off-by: John Stultz --- drivers/staging/android/ion/ion_page_pool.c | 150 ++++++++++++++++++++++------ drivers/staging/android/ion/ion_priv.h | 3 +- 2 files changed, 123 insertions(+), 30 deletions(-) diff --git a/drivers/staging/android/ion/ion_page_pool.c b/drivers/staging/android/ion/ion_page_pool.c index 20790eb..e59da3a 100644 --- a/drivers/staging/android/ion/ion_page_pool.c +++ b/drivers/staging/android/ion/ion_page_pool.c @@ -14,13 +14,21 @@ * */ +#include #include #include +#include #include +#include #include #include #include "ion_priv.h" +/* #define DEBUG_PAGE_POOL_SHRINKER */ + +static struct plist_head pools = PLIST_HEAD_INIT(pools); +static struct shrinker shrinker; + struct ion_page_pool_item { struct page *page; struct list_head list; @@ -118,46 +126,110 @@ void ion_page_pool_free(struct ion_page_pool *pool, struct page* page) ion_page_pool_free_pages(pool, page); } +#ifdef DEBUG_PAGE_POOL_SHRINKER +static int debug_drop_pools_set(void *data, u64 val) +{ + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + if (!val) + return 0; + + objs = shrinker.shrink(&shrinker, &sc); + sc.nr_to_scan = objs; + + shrinker.shrink(&shrinker, &sc); + return 0; +} + +static int debug_drop_pools_get(void *data, u64 *val) +{ + struct shrink_control sc; + int objs; + + sc.gfp_mask = -1; + sc.nr_to_scan = 0; + + objs = shrinker.shrink(&shrinker, &sc); + *val = objs; + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_drop_pools_fops, debug_drop_pools_get, + debug_drop_pools_set, "%llu\n"); + +static int debug_grow_pools_set(void *data, u64 val) +{ + struct ion_page_pool *pool; + struct page *page; + + plist_for_each_entry(pool, &pools, list) { + if (val != pool->list.prio) + continue; + page = ion_page_pool_alloc_pages(pool); + if (page) + ion_page_pool_add(pool, page); + } + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(debug_grow_pools_fops, debug_drop_pools_get, + debug_grow_pools_set, "%llu\n"); +#endif + +static int ion_page_pool_total(bool high) +{ + struct ion_page_pool *pool; + int total = 0; + + plist_for_each_entry(pool, &pools, list) { + total += high ? (pool->high_count + pool->low_count) * + (1 << pool->order) : + pool->low_count * (1 << pool->order); + } + return total; +} + static int ion_page_pool_shrink(struct shrinker *shrinker, struct shrink_control *sc) { - struct ion_page_pool *pool = container_of(shrinker, - struct ion_page_pool, - shrinker); + struct ion_page_pool *pool; int nr_freed = 0; int i; bool high; + int nr_to_scan = sc->nr_to_scan; if (sc->gfp_mask & __GFP_HIGHMEM) high = true; - if (sc->nr_to_scan == 0) - return high ? (pool->high_count + pool->low_count) * - (1 << pool->order) : - pool->low_count * (1 << pool->order); + if (nr_to_scan == 0) + return ion_page_pool_total(high); - for (i = 0; i < sc->nr_to_scan; i++) { - struct page *page; + plist_for_each_entry(pool, &pools, list) { + for (i = 0; i < nr_to_scan; i++) { + struct page *page; - mutex_lock(&pool->mutex); - if (high && pool->high_count) { - page = ion_page_pool_remove(pool, true); - } else if (pool->low_count) { - page = ion_page_pool_remove(pool, false); - } else { + mutex_lock(&pool->mutex); + if (high && pool->high_count) { + page = ion_page_pool_remove(pool, true); + } else if (pool->low_count) { + page = ion_page_pool_remove(pool, false); + } else { + mutex_unlock(&pool->mutex); + break; + } mutex_unlock(&pool->mutex); - break; + ion_page_pool_free_pages(pool, page); + nr_freed += (1 << pool->order); } - mutex_unlock(&pool->mutex); - ion_page_pool_free_pages(pool, page); - nr_freed += (1 << pool->order); + nr_to_scan -= i; } - pr_info("%s: shrunk page_pool of order %d by %d pages\n", __func__, - pool->order, nr_freed); - return high ? (pool->high_count + pool->low_count) * - (1 << pool->order) : - pool->low_count * (1 << pool->order); + return ion_page_pool_total(high); } struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) @@ -170,20 +242,40 @@ struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) pool->low_count = 0; INIT_LIST_HEAD(&pool->low_items); INIT_LIST_HEAD(&pool->high_items); - pool->shrinker.shrink = ion_page_pool_shrink; - pool->shrinker.seeks = DEFAULT_SEEKS * 16; - pool->shrinker.batch = 0; - register_shrinker(&pool->shrinker); pool->gfp_mask = gfp_mask; pool->order = order; mutex_init(&pool->mutex); + plist_node_init(&pool->list, order); + plist_add(&pool->list, &pools); return pool; } void ion_page_pool_destroy(struct ion_page_pool *pool) { - unregister_shrinker(&pool->shrinker); + plist_del(&pool->list, &pools); kfree(pool); } +static int __init ion_page_pool_init(void) +{ + shrinker.shrink = ion_page_pool_shrink; + shrinker.seeks = DEFAULT_SEEKS; + shrinker.batch = 0; + register_shrinker(&shrinker); +#ifdef DEBUG_PAGE_POOL_SHRINKER + debugfs_create_file("ion_pools_shrink", 0644, NULL, NULL, + &debug_drop_pools_fops); + debugfs_create_file("ion_pools_grow", 0644, NULL, NULL, + &debug_grow_pools_fops); +#endif + return 0; +} + +static void __exit ion_page_pool_exit(void) +{ + unregister_shrinker(&shrinker); +} + +module_init(ion_page_pool_init); +module_exit(ion_page_pool_exit); diff --git a/drivers/staging/android/ion/ion_priv.h b/drivers/staging/android/ion/ion_priv.h index beb1595..77e2ac0 100644 --- a/drivers/staging/android/ion/ion_priv.h +++ b/drivers/staging/android/ion/ion_priv.h @@ -230,6 +230,7 @@ void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr, * when the shrinker fires * @gfp_mask: gfp_mask to use from alloc * @order: order of pages in the pool + * @list: plist node for list of pools * * Allows you to keep a pool of pre allocated pages to use from your heap. * Keeping a pool of pages that is ready for dma, ie any cached mapping have @@ -241,12 +242,12 @@ struct ion_page_pool { int low_count; struct list_head high_items; struct list_head low_items; - struct shrinker shrinker; struct mutex mutex; void *(*alloc)(struct ion_page_pool *pool); void (*free)(struct ion_page_pool *pool, struct page *page); gfp_t gfp_mask; unsigned int order; + struct plist_node list; }; struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order);