msm: kgsl: Try lower order mempools incase of mismatch

Try to allocate pages from lower order mempools incase
if requested memory size order does not match with the
available mempools.

Change-Id: Idbe4dae3b8bb2a3165199b6959ad4fbf36559964
Signed-off-by: Rajesh Kemisetti <rajeshk@codeaurora.org>
This commit is contained in:
Rajesh Kemisetti 2017-01-19 22:20:23 +05:30
parent 1f1d944084
commit 1664a92367

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -299,6 +299,7 @@ int kgsl_pool_alloc_page(int *page_size, struct page **pages,
struct page *p = NULL;
int order = get_order(*page_size);
int pool_idx;
size_t size = 0;
if ((pages == NULL) || pages_len < (*page_size >> PAGE_SHIFT))
return -EINVAL;
@ -311,11 +312,8 @@ int kgsl_pool_alloc_page(int *page_size, struct page **pages,
if (page == NULL) {
/* Retry with lower order pages */
if (order > 0) {
size_t size = PAGE_SIZE << --order;
*page_size = kgsl_get_page_size(size,
ilog2(size));
*align = ilog2(*page_size);
return -EAGAIN;
size = PAGE_SIZE << --order;
goto eagain;
} else
return -ENOMEM;
@ -325,8 +323,25 @@ int kgsl_pool_alloc_page(int *page_size, struct page **pages,
}
pool = _kgsl_get_pool_from_order(order);
if (pool == NULL)
return -EINVAL;
if (pool == NULL) {
/* Retry with lower order pages */
if (order > 0) {
size = PAGE_SIZE << --order;
goto eagain;
} else {
/*
* Fall back to direct allocation in case
* pool with zero order is not present
*/
gfp_t gfp_mask = kgsl_gfp_mask(order);
page = alloc_pages(gfp_mask, order);
if (page == NULL)
return -ENOMEM;
_kgsl_pool_zero_page(page, order);
goto done;
}
}
pool_idx = kgsl_pool_idx_lookup(order);
page = _kgsl_pool_get_page(pool);
@ -337,10 +352,9 @@ int kgsl_pool_alloc_page(int *page_size, struct page **pages,
/* Only allocate non-reserved memory for certain pools */
if (!pool->allocation_allowed && pool_idx > 0) {
*page_size = PAGE_SIZE <<
size = PAGE_SIZE <<
kgsl_pools[pool_idx-1].pool_order;
*align = ilog2(*page_size);
return -EAGAIN;
goto eagain;
}
page = alloc_pages(gfp_mask, order);
@ -348,10 +362,9 @@ int kgsl_pool_alloc_page(int *page_size, struct page **pages,
if (!page) {
if (pool_idx > 0) {
/* Retry with lower order pages */
*page_size = PAGE_SIZE <<
size = PAGE_SIZE <<
kgsl_pools[pool_idx-1].pool_order;
*align = ilog2(*page_size);
return -EAGAIN;
goto eagain;
} else
return -ENOMEM;
}
@ -367,6 +380,12 @@ done:
}
return pcount;
eagain:
*page_size = kgsl_get_page_size(size,
ilog2(size));
*align = ilog2(*page_size);
return -EAGAIN;
}
void kgsl_pool_free_page(struct page *page)