ttm_pool_free() only trims the cache of the pool's default node. With pages allocated on other nodes, check each node's limit on free. The per-node accounting and shrinker already exist in TTM.
Signed-off-by: Himal Prasad Ghimiray <[email protected]> --- drivers/gpu/drm/ttm/ttm_pool.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 2107dc6c69b3..faba20cef216 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -1050,13 +1050,20 @@ int ttm_pool_restore_and_alloc_node(struct ttm_pool *pool, struct ttm_tt *tt, */ void ttm_pool_free(struct ttm_pool *pool, struct ttm_tt *tt) { - int nid = ttm_pool_nid(pool); + int nid; ttm_pool_free_range(pool, tt, tt->caching, 0, tt->num_pages); - while (atomic_long_read(&allocated_pages[nid]) > pool_node_limit[nid]) { - unsigned long diff = atomic_long_read(&allocated_pages[nid]) - pool_node_limit[nid]; - ttm_pool_shrink(nid, diff); + /* + * ttm_pool_alloc_node() can place pages on a caller-requested node, so + * freed pages may land on any node's cache; enforce every node's limit. + */ + for_each_node(nid) { + unsigned long cached; + + while ((cached = atomic_long_read(&allocated_pages[nid])) > + pool_node_limit[nid]) + ttm_pool_shrink(nid, cached - pool_node_limit[nid]); } } EXPORT_SYMBOL(ttm_pool_free); -- 2.43.0
