Commit 84d5d76c authored by Matthew Brost's avatar Matthew Brost
Browse files

drm/ttm: Fix GPU MM stats during pool shrinking



TTM pool shrinking frees pages by calling __free_pages() directly,
which bypasses updates to NR_GPU_ACTIVE and leaves GPU MM accounting
out of sync.

Introduce a helper, __free_pages_gpu_account(), and use it for all page
frees in ttm_pool.c so GPU MM statistics are updated consistently.

Reported-by: default avatarKenneth Crudup <kenny@panix.com>
Fixes: ae80122f ("drm/ttm: use gpu mm stats to track gpu memory allocations. (v4)")
Cc: Christian Koenig <christian.koenig@amd.com>
Cc: Huang Rui <ray.huang@amd.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: David Airlie <airlied@gmail.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: default avatarMatthew Brost <matthew.brost@intel.com>
Tested-by: default avatarKenneth Crudup <kenny@panix.com>
Reviewed-by: default avatarDave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20260502065338.2720646-1-matthew.brost@intel.com
parent 01eb80b7
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -206,6 +206,14 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
	return NULL;
}

static void __free_pages_gpu_account(struct page *p, unsigned int order,
				     bool reclaim)
{
	mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
			      -(1 << order));
	__free_pages(p, order);
}

/* Reset the caching and pages of size 1 << order */
static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
			       unsigned int order, struct page *p, bool reclaim)
@@ -223,9 +231,7 @@ static void ttm_pool_free_page(struct ttm_pool *pool, enum ttm_caching caching,
#endif

	if (!pool || !ttm_pool_uses_dma_alloc(pool)) {
		mod_lruvec_page_state(p, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE,
				      -(1 << order));
		__free_pages(p, order);
		__free_pages_gpu_account(p, order, reclaim);
		return;
	}

@@ -606,7 +612,7 @@ static int ttm_pool_restore_commit(struct ttm_pool_tt_restore *restore,
			 */
			ttm_pool_split_for_swap(restore->pool, p);
			copy_highpage(restore->alloced_page + i, p);
			__free_pages(p, 0);
			__free_pages_gpu_account(p, 0, false);
		}

		restore->restored_pages++;
@@ -1068,7 +1074,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
			if (flags->purge) {
				shrunken += num_pages;
				page->private = 0;
				__free_pages(page, order);
				__free_pages_gpu_account(page, order, false);
				memset(tt->pages + i, 0,
				       num_pages * sizeof(*tt->pages));
			}
@@ -1109,7 +1115,7 @@ long ttm_pool_backup(struct ttm_pool *pool, struct ttm_tt *tt,
		}
		handle = shandle;
		tt->pages[i] = ttm_backup_handle_to_page_ptr(handle);
		put_page(page);
		__free_pages_gpu_account(page, 0, false);
		shrunken++;
	}