[PATCH] drm/msm: avoid an unmatched fbdev IOVA pin

From: Michael McAllister

Date: Mon Nov 09 2026 - 12:14:19 EST


Unbinding the display on the Moto G10 produces a pin-count warning when
the console framebuffer is freed. The fbdev probe takes an IOVA pin,
but normal teardown never drops it.

Use msm_gem_get_iova() to reserve the address without taking that extra
pin. Scanout already pins the buffer while it is in use, and the CPU
mapping holds its own pin. Drop the matching unpin from the error path.

Fixes: 7ad0e8cf6317 ("drm/msm: Count how many times iova memory is pinned")
Signed-off-by: Michael McAllister <me@xxxxxxxxxxxxxxxxxxxxx>
---
Hi,

I found another pin-count warning while testing display teardown on the
Moto G10. This one is in fbdev: it takes a pin when creating the console
framebuffer, but doesn't drop it when the framebuffer is freed.

I tested this alongside the other display fixes on 7.2.9, including
unbind/rebind with the compositor stopped. It is independent of the DSI
command-buffer fix I sent earlier.

Thanks,
Michael

drivers/gpu/drm/msm/msm_fbdev.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index dd6d6c507d..c3bec6719c 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -137,12 +137,8 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
goto err_drm_gem_handle_delete;
}

- /*
- * NOTE: if we can be guaranteed to be able to map buffer
- * in panic (ie. lock-safe, etc) we could avoid pinning the
- * buffer now:
- */
- ret = msm_gem_get_and_pin_iova(bo, priv->kms->vm, &paddr);
+ /* Scanout pins the buffer; only reserve its address here. */
+ ret = msm_gem_get_iova(bo, priv->kms->vm, &paddr);
if (ret) {
drm_err(dev, "failed to get buffer obj iova: %d\n", ret);
goto err_drm_client_buffer_delete;
@@ -162,7 +158,7 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,
fbi->screen_buffer = msm_gem_get_vaddr(bo);
if (IS_ERR(fbi->screen_buffer)) {
ret = PTR_ERR(fbi->screen_buffer);
- goto err_msm_gem_unpin;
+ goto err_msm_gem_vma_put;
}
fbi->screen_size = bo->size;
fbi->fix.smem_start = paddr;
@@ -179,8 +175,7 @@ int msm_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper,

return 0;

-err_msm_gem_unpin:
- msm_gem_unpin_iova(bo, priv->kms->vm);
+err_msm_gem_vma_put:
msm_gem_vma_put(bo);
err_drm_client_buffer_delete:
drm_client_buffer_delete(buffer);

base-commit: 1e59855738454b14021b64115f0090eafc7526ae
--
2.39.5