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:
Deepak Kumar 2021-05-20 19:34:14 +05:30
commit c33a7cb617

View file

@ -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;