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

Reply via email to