aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König2022-11-07 20:40:11 +0100
committerGreg Kroah-Hartman2023-05-11 23:03:13 +0900
commit5e5a4185c66f9478a8cb2f74eed1a5b5a5000b13 (patch)
tree7b042f6f2b3bc130524828b712fae287eb8156d5
parentdfd1c26e40b521d22ea8aeb14078dbde6843a25f (diff)
drm/ttm: optimize pool allocations a bit v2
[ Upstream commit 735c466465eba51deaee3012d8403c10fc7c8c03 ] If we got a page pool use it as much as possible. If we can't get more pages from the pool allocate as much as possible. Only if that still doesn't work reduce the order and try again. v2: minor cleanups Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20221107195808.1873-1-christian.koenig@amd.com Stable-dep-of: 379989e7cbdc ("drm/ttm/pool: Fix ttm_pool_alloc error path") Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/gpu/drm/ttm/ttm_pool.c82
1 files changed, 58 insertions, 24 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c
index 21b61631f73a..9f6764bf3b15 100644
--- a/drivers/gpu/drm/ttm/ttm_pool.c
+++ b/drivers/gpu/drm/ttm/ttm_pool.c
@@ -344,6 +344,28 @@ static unsigned int ttm_pool_page_order(struct ttm_pool *pool, struct page *p)
return p->private;
}
+/* Called when we got a page, either from a pool or newly allocated */
+static int ttm_pool_page_allocated(struct ttm_pool *pool, unsigned int order,
+ struct page *p, dma_addr_t **dma_addr,
+ unsigned long *num_pages,
+ struct page ***pages)
+{
+ unsigned int i;
+ int r;
+
+ if (*dma_addr) {
+ r = ttm_pool_map(pool, order, p, dma_addr);
+ if (r)
+ return r;
+ }
+
+ *num_pages -= 1 << order;
+ for (i = 1 << order; i; --i, ++(*pages), ++p)
+ **pages = p;
+
+ return 0;
+}
+
/**
* ttm_pool_alloc - Fill a ttm_tt object
*
@@ -385,45 +407,57 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
for (order = min_t(unsigned int, MAX_ORDER - 1, __fls(num_pages));
num_pages;
order = min_t(unsigned int, order, __fls(num_pages))) {
- bool apply_caching = false;
struct ttm_pool_type *pt;
pt = ttm_pool_select_type(pool, tt->caching, order);
p = pt ? ttm_pool_type_take(pt) : NULL;
if (p) {
- apply_caching = true;
- } else {
- p = ttm_pool_alloc_page(pool, gfp_flags, order);
- if (p && PageHighMem(p))
- apply_caching = true;
- }
-
- if (!p) {
- if (order) {
- --order;
- continue;
- }
- r = -ENOMEM;
- goto error_free_all;
- }
-
- if (apply_caching) {
r = ttm_pool_apply_caching(caching, pages,
tt->caching);
if (r)
goto error_free_page;
- caching = pages + (1 << order);
+
+ do {
+ r = ttm_pool_page_allocated(pool, order, p,
+ &dma_addr,
+ &num_pages,
+ &pages);
+ if (r)
+ goto error_free_page;
+
+ if (num_pages < (1 << order))
+ break;
+
+ p = ttm_pool_type_take(pt);
+ } while (p);
+ caching = pages;
}
- if (dma_addr) {
- r = ttm_pool_map(pool, order, p, &dma_addr);
+ while (num_pages >= (1 << order) &&
+ (p = ttm_pool_alloc_page(pool, gfp_flags, order))) {
+
+ if (PageHighMem(p)) {
+ r = ttm_pool_apply_caching(caching, pages,
+ tt->caching);
+ if (r)
+ goto error_free_page;
+ }
+ r = ttm_pool_page_allocated(pool, order, p, &dma_addr,
+ &num_pages, &pages);
if (r)
goto error_free_page;
+ if (PageHighMem(p))
+ caching = pages;
}
- num_pages -= 1 << order;
- for (i = 1 << order; i; --i)
- *(pages++) = p++;
+ if (!p) {
+ if (order) {
+ --order;
+ continue;
+ }
+ r = -ENOMEM;
+ goto error_free_all;
+ }
}
r = ttm_pool_apply_caching(caching, pages, tt->caching);