Use page_alloc_exact() to get buffers, instead of get_free_pages(), so as to avoid wastage of memory. Currently get_free_pages() is allocating at next order, while page_alloc_exact() will free the unused pages.
Signed-off-by: Devaraj Rangasamy Devaraj.Rangasamy@amd.com --- v2: * Replaced __get_free_pages() with alloc_pages_exact().
drivers/tee/amdtee/shm_pool.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/tee/amdtee/shm_pool.c b/drivers/tee/amdtee/shm_pool.c index f0303126f199..156e8a6f631f 100644 --- a/drivers/tee/amdtee/shm_pool.c +++ b/drivers/tee/amdtee/shm_pool.c @@ -4,6 +4,7 @@ */
#include <linux/slab.h> +#include <linux/mm.h> #include <linux/tee_drv.h> #include <linux/psp.h> #include "amdtee_private.h" @@ -11,26 +12,23 @@ static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align) { - unsigned int order = get_order(size); - unsigned long va; + void *va; int rc;
- /* - * Ignore alignment since this is already going to be page aligned - * and there's no need for any larger alignment. - */ - va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); + size = PAGE_ALIGN(size); + + va = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); if (!va) return -ENOMEM;
shm->kaddr = (void *)va; shm->paddr = __psp_pa((void *)va); - shm->size = PAGE_SIZE << order; + shm->size = size;
/* Map the allocated memory in to TEE */ rc = amdtee_map_shmem(shm); if (rc) { - free_pages(va, order); + free_pages_exact(va, size); shm->kaddr = NULL; return rc; } @@ -42,7 +40,7 @@ static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) { /* Unmap the shared memory from TEE */ amdtee_unmap_shmem(shm); - free_pages((unsigned long)shm->kaddr, get_order(shm->size)); + free_pages_exact(shm->kaddr, shm->size); shm->kaddr = NULL; }
amdtee driver shall use CMA region for contiguous buffer allocation, if CMA is available.
since CMA and DMA contiguous APIs are not exported, this support is enabled only when amdtee is built as a builtin driver.
Signed-off-by: Devaraj Rangasamy Devaraj.Rangasamy@amd.com Signed-off-by: SivaSangeetha SK SivaSangeetha.SK@amd.com Reviewed-by: Rijo Thomas Rijo-john.Thomas@amd.com --- v2: * Switched to generic CMA pool. * Replaced __get_free_pages() with alloc_pages_exact(). * Compacted patch with simplified changes within single file.
drivers/tee/amdtee/shm_pool.c | 51 +++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/drivers/tee/amdtee/shm_pool.c b/drivers/tee/amdtee/shm_pool.c index 156e8a6f631f..d504d9749114 100644 --- a/drivers/tee/amdtee/shm_pool.c +++ b/drivers/tee/amdtee/shm_pool.c @@ -5,10 +5,50 @@
#include <linux/slab.h> #include <linux/mm.h> +#include <linux/dma-map-ops.h> #include <linux/tee_drv.h> #include <linux/psp.h> #include "amdtee_private.h"
+#if IS_BUILTIN(CONFIG_AMDTEE) && IS_ENABLED(CONFIG_DMA_CMA) +static void *alloc_from_cma(size_t size) +{ + + int nr_pages = size >> PAGE_SHIFT; + struct page *page; + + page = dma_alloc_from_contiguous(NULL, nr_pages, 0, false); + if (page) + return page_to_virt(page); + + return NULL; +} + +static bool free_from_cma(struct tee_shm *shm) +{ + + int nr_pages; + struct page *page; + + if (!dev_get_cma_area(NULL)) + return false; + + nr_pages = shm->size >> PAGE_SHIFT; + page = virt_to_page(shm->kaddr); + return dma_release_from_contiguous(NULL, page, nr_pages); +} +#else +static void *alloc_from_cma(size_t size) +{ + return NULL; +} + +static bool free_from_cma(struct tee_shm *shm) +{ + return false; +} +#endif + static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align) { @@ -17,7 +57,11 @@ static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm,
size = PAGE_ALIGN(size);
- va = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); + va = alloc_from_cma(size); + + if (!va) + va = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); + if (!va) return -ENOMEM;
@@ -40,7 +84,10 @@ static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) { /* Unmap the shared memory from TEE */ amdtee_unmap_shmem(shm); - free_pages_exact(shm->kaddr, shm->size); + + if (!free_from_cma(shm)) + free_pages_exact(shm->kaddr, shm->size); + shm->kaddr = NULL; }
On 8/30/2023 1:49 AM, Devaraj Rangasamy wrote:
Use page_alloc_exact() to get buffers, instead of get_free_pages(), so as to avoid wastage of memory. Currently get_free_pages() is allocating at next order, while page_alloc_exact() will free the unused pages.
Signed-off-by: Devaraj Rangasamy Devaraj.Rangasamy@amd.com
v2:
- Replaced __get_free_pages() with alloc_pages_exact().
Reviewed-by: Rijo Thomas Rijo-john.Thomas@amd.com
Thanks, Rijo
drivers/tee/amdtee/shm_pool.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/tee/amdtee/shm_pool.c b/drivers/tee/amdtee/shm_pool.c index f0303126f199..156e8a6f631f 100644 --- a/drivers/tee/amdtee/shm_pool.c +++ b/drivers/tee/amdtee/shm_pool.c @@ -4,6 +4,7 @@ */ #include <linux/slab.h> +#include <linux/mm.h> #include <linux/tee_drv.h> #include <linux/psp.h> #include "amdtee_private.h" @@ -11,26 +12,23 @@ static int pool_op_alloc(struct tee_shm_pool *pool, struct tee_shm *shm, size_t size, size_t align) {
- unsigned int order = get_order(size);
- unsigned long va;
- void *va; int rc;
- /*
* Ignore alignment since this is already going to be page aligned
* and there's no need for any larger alignment.
*/
- va = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
- size = PAGE_ALIGN(size);
- va = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); if (!va) return -ENOMEM;
shm->kaddr = (void *)va; shm->paddr = __psp_pa((void *)va);
- shm->size = PAGE_SIZE << order;
- shm->size = size;
/* Map the allocated memory in to TEE */ rc = amdtee_map_shmem(shm); if (rc) {
free_pages(va, order);
shm->kaddr = NULL; return rc; }free_pages_exact(va, size);
@@ -42,7 +40,7 @@ static void pool_op_free(struct tee_shm_pool *pool, struct tee_shm *shm) { /* Unmap the shared memory from TEE */ amdtee_unmap_shmem(shm);
- free_pages((unsigned long)shm->kaddr, get_order(shm->size));
- free_pages_exact(shm->kaddr, shm->size); shm->kaddr = NULL;
}
On 8/29/2023 1:19 PM, Devaraj Rangasamy wrote:> Use page_alloc_exact() to get buffers, instead of
get_free_pages(), so as to avoid wastage of memory. Currently get_free_pages() is allocating at next order, while page_alloc_exact() will free the unused pages.
s/page_alloc_exact()/alloc_pages_exact()/ everywhere including subject to match the actual code change?
On 10/5/2023 12:39 AM, Jeff Johnson wrote:
On 8/29/2023 1:19 PM, Devaraj Rangasamy wrote:> Use page_alloc_exact() to get buffers, instead of
get_free_pages(), so as to avoid wastage of memory. Currently get_free_pages() is allocating at next order, while page_alloc_exact() will free the unused pages.
s/page_alloc_exact()/alloc_pages_exact()/ everywhere including subject to match the actual code change?
Ack. Thanks for the catching this.
While I could send an updated patch taking care of this, we are working on a rearchitected patch, due to a new requirement.
Kindly abandon this patch series, and we will be posting new support soon to the community.
op-tee@lists.trustedfirmware.org