Pinned bos aren't shinkable and needs to be removed from the shrinkable accounting. Do that, and in the process constify the tt argument to ttm_tt_is_populated. Signed-off-by: Thomas Hellström <thomas.hellstrom@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/ttm/ttm_bo.c | 7 +++++++ drivers/gpu/drm/ttm/ttm_tt.c | 22 ++++++++++++++++++++++ include/drm/ttm/ttm_tt.h | 6 +++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index e5c0970564c0..e59e2a4605d0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -650,6 +650,10 @@ void ttm_bo_pin(struct ttm_buffer_object *bo) { dma_resv_assert_held(bo->base.resv); WARN_ON_ONCE(!kref_read(&bo->kref)); + + if (!bo->pin_count && bo->ttm) + ttm_tt_set_pinned(bo->bdev, bo->ttm); + spin_lock(&bo->bdev->lru_lock); if (bo->resource) ttm_resource_del_bulk_move(bo->resource, bo); @@ -671,6 +675,9 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo) if (WARN_ON_ONCE(!bo->pin_count)) return; + if (bo->pin_count == 1 && bo->ttm) + ttm_tt_set_unpinned(bo->bdev, bo->ttm); + spin_lock(&bo->bdev->lru_lock); --bo->pin_count; if (bo->resource) diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 848adf2a623e..a39c617c7a8e 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -83,6 +83,28 @@ static void ttm_tt_mod_shrinkable_pages(long shrinkable, long purgeable) write_unlock(&shrinkable_lock); } +/** + * ttm_tt_set_pinned() - Modify the shinkable accounting when pinning a bo. + * @bdev: The TTM device. + * @tt: The struct tt_tt used by the pinned bo. + */ +void ttm_tt_set_pinned(const struct ttm_device *bdev, const struct ttm_tt *tt) +{ + if (ttm_tt_shrinkable(bdev, tt) && ttm_tt_is_populated(tt)) + ttm_tt_mod_shrinkable_pages(-(long)tt->num_pages, 0); +} + +/** + * ttm_tt_set_unpinned() - Modify the shinkable accounting when unpinning a bo. + * @bdev: The TTM device. + * @tt: The struct tt_tt used by the no longer pinned bo. + */ +void ttm_tt_set_unpinned(const struct ttm_device *bdev, const struct ttm_tt *tt) +{ + if (ttm_tt_shrinkable(bdev, tt) && ttm_tt_is_populated(tt)) + ttm_tt_mod_shrinkable_pages(tt->num_pages, 0); +} + /* * Allocates a ttm structure for the given BO. */ diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h index 3f99787e2b93..69467671c2dd 100644 --- a/include/drm/ttm/ttm_tt.h +++ b/include/drm/ttm/ttm_tt.h @@ -118,7 +118,7 @@ struct ttm_kmap_iter_tt { pgprot_t prot; }; -static inline bool ttm_tt_is_populated(struct ttm_tt *tt) +static inline bool ttm_tt_is_populated(const struct ttm_tt *tt) { return tt->page_flags & TTM_TT_FLAG_PRIV_POPULATED; } @@ -238,6 +238,10 @@ static inline bool ttm_tt_purgeable(struct ttm_tt *tt) return tt->page_flags & TTM_TT_FLAG_DONTNEED; } +void ttm_tt_set_pinned(const struct ttm_device *bdev, const struct ttm_tt *tt); + +void ttm_tt_set_unpinned(const struct ttm_device *bdev, const struct ttm_tt *tt); + #if IS_ENABLED(CONFIG_AGP) #include <linux/agp_backend.h> -- 2.34.1