mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
msm: kgsl: Fix num_pages calculation while shrinking pool
Correct num_pages calculation to ensure shrinker is able to free pages from higher order pools and also make sure shrinker is not able to free pages from pool beyond reserved pages. Change-Id: Iedefe74caca7d04bf4b8e25915e8470929688424 Signed-off-by: Deepak Kumar <dkumar@codeaurora.org>
This commit is contained in:
parent
610e9488fb
commit
c33a7cb617
1 changed files with 37 additions and 6 deletions
|
|
@ -150,6 +150,35 @@ static int kgsl_pool_size_total(void)
|
|||
return total;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a page from specified pool only if pool
|
||||
* currently holds more number of pages than reserved
|
||||
* pages.
|
||||
*/
|
||||
static struct page *
|
||||
_kgsl_pool_get_nonreserved_page(struct kgsl_page_pool *pool)
|
||||
{
|
||||
struct page *p = NULL;
|
||||
|
||||
spin_lock(&pool->list_lock);
|
||||
if (pool->page_count <= pool->reserved_pages) {
|
||||
spin_unlock(&pool->list_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = list_first_entry_or_null(&pool->page_list, struct page, lru);
|
||||
if (p == NULL) {
|
||||
spin_unlock(&pool->list_lock);
|
||||
return NULL;
|
||||
}
|
||||
pool->page_count--;
|
||||
list_del(&p->lru);
|
||||
spin_unlock(&pool->list_lock);
|
||||
mod_node_page_state(page_pgdat(p), NR_KERNEL_MISC_RECLAIMABLE,
|
||||
-(1 << pool->pool_order));
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* This will shrink the specified pool by num_pages or by
|
||||
* (page_count - reserved_pages), whichever is smaller.
|
||||
|
|
@ -160,19 +189,21 @@ _kgsl_pool_shrink(struct kgsl_page_pool *pool,
|
|||
{
|
||||
int j;
|
||||
unsigned int pcount = 0;
|
||||
struct page *(*get_page)(struct kgsl_page_pool *) =
|
||||
_kgsl_pool_get_nonreserved_page;
|
||||
|
||||
if (pool == NULL || num_pages == 0)
|
||||
return pcount;
|
||||
|
||||
num_pages = num_pages >> pool->pool_order;
|
||||
num_pages = (num_pages + (1 << pool->pool_order) - 1) >>
|
||||
pool->pool_order;
|
||||
|
||||
/* This is to ensure that we don't free reserved pages */
|
||||
if (!exit)
|
||||
num_pages = min(num_pages, (pool->page_count -
|
||||
pool->reserved_pages));
|
||||
/* This is to ensure that we free reserved pages */
|
||||
if (exit)
|
||||
get_page = _kgsl_pool_get_page;
|
||||
|
||||
for (j = 0; j < num_pages; j++) {
|
||||
struct page *page = _kgsl_pool_get_page(pool);
|
||||
struct page *page = get_page(pool);
|
||||
|
||||
if (!page)
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue