--- zzzz-none-000/linux-4.4.271/drivers/staging/android/ion/ion_page_pool.c 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/drivers/staging/android/ion/ion_page_pool.c 2023-04-19 10:22:29.000000000 +0000 @@ -1,5 +1,5 @@ /* - * drivers/staging/android/ion/ion_mem_pool.c + * drivers/staging/android/ion/ion_page_pool.c * * Copyright (C) 2011 Google, Inc. * @@ -22,22 +22,35 @@ #include #include #include +#include #include "ion_priv.h" static void *ion_page_pool_alloc_pages(struct ion_page_pool *pool) { - struct page *page = alloc_pages(pool->gfp_mask, pool->order); + struct page *page; + + page = alloc_pages(pool->gfp_mask & ~__GFP_ZERO, pool->order); if (!page) return NULL; - ion_pages_sync_for_device(NULL, page, PAGE_SIZE << pool->order, - DMA_BIDIRECTIONAL); + + if (pool->gfp_mask & __GFP_ZERO) + if (msm_ion_heap_high_order_page_zero(pool->dev, page, + pool->order)) + goto error_free_pages; + + ion_page_pool_alloc_set_cache_policy(pool, page); + return page; +error_free_pages: + __free_pages(page, pool->order); + return NULL; } static void ion_page_pool_free_pages(struct ion_page_pool *pool, struct page *page) { + ion_page_pool_free_set_cache_policy(pool, page); __free_pages(page, pool->order); } @@ -51,6 +64,9 @@ list_add_tail(&page->lru, &pool->low_items); pool->low_count++; } + + mod_zone_page_state(page_zone(page), NR_INDIRECTLY_RECLAIMABLE_BYTES, + (1 << (PAGE_SHIFT + pool->order))); mutex_unlock(&pool->mutex); return 0; } @@ -70,24 +86,49 @@ } list_del(&page->lru); + mod_zone_page_state(page_zone(page), NR_INDIRECTLY_RECLAIMABLE_BYTES, + -(1 << (PAGE_SHIFT + pool->order))); return page; } -struct page *ion_page_pool_alloc(struct ion_page_pool *pool) +void *ion_page_pool_alloc(struct ion_page_pool *pool, bool *from_pool) { struct page *page = NULL; BUG_ON(!pool); - mutex_lock(&pool->mutex); - if (pool->high_count) - page = ion_page_pool_remove(pool, true); - else if (pool->low_count) - page = ion_page_pool_remove(pool, false); - mutex_unlock(&pool->mutex); + *from_pool = true; - if (!page) + if (mutex_trylock(&pool->mutex)) { + if (pool->high_count) + page = ion_page_pool_remove(pool, true); + else if (pool->low_count) + page = ion_page_pool_remove(pool, false); + mutex_unlock(&pool->mutex); + } + if (!page) { page = ion_page_pool_alloc_pages(pool); + *from_pool = false; + } + return page; +} + +/* + * Tries to allocate from only the specified Pool and returns NULL otherwise + */ +void *ion_page_pool_alloc_pool_only(struct ion_page_pool *pool) +{ + struct page *page = NULL; + + BUG_ON(!pool); + + if (mutex_trylock(&pool->mutex)) { + if (pool->high_count) + page = ion_page_pool_remove(pool, true); + else if (pool->low_count) + page = ion_page_pool_remove(pool, false); + mutex_unlock(&pool->mutex); + } return page; } @@ -96,14 +137,17 @@ { int ret; - BUG_ON(pool->order != compound_order(page)); - ret = ion_page_pool_add(pool, page); if (ret) ion_page_pool_free_pages(pool, page); } -static int ion_page_pool_total(struct ion_page_pool *pool, bool high) +void ion_page_pool_free_immediate(struct ion_page_pool *pool, struct page *page) +{ + ion_page_pool_free_pages(pool, page); +} + +int ion_page_pool_total(struct ion_page_pool *pool, bool high) { int count = pool->low_count; @@ -147,17 +191,19 @@ return freed; } -struct ion_page_pool *ion_page_pool_create(gfp_t gfp_mask, unsigned int order) +struct ion_page_pool *ion_page_pool_create(struct device *dev, gfp_t gfp_mask, + unsigned int order) { struct ion_page_pool *pool = kmalloc(sizeof(struct ion_page_pool), GFP_KERNEL); if (!pool) return NULL; + pool->dev = dev; pool->high_count = 0; pool->low_count = 0; INIT_LIST_HEAD(&pool->low_items); INIT_LIST_HEAD(&pool->high_items); - pool->gfp_mask = gfp_mask | __GFP_COMP; + pool->gfp_mask = gfp_mask; pool->order = order; mutex_init(&pool->mutex); plist_node_init(&pool->list, order);