]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/gem-shmem: Track folio accessed/dirty status in vmap
authorThomas Zimmermann <tzimmermann@suse.de>
Fri, 27 Feb 2026 11:42:11 +0000 (12:42 +0100)
committerThomas Zimmermann <tzimmermann@suse.de>
Wed, 11 Mar 2026 08:33:43 +0000 (09:33 +0100)
On successful vmap, set the page_mark_accessed_on_put and _dirty_on_put
flags in the gem-shmem object. Signals that the contained pages require
LRU and dirty tracking when they are being released back to SHMEM. Clear
these flags on put, so that the buffer remains quiet until the next call
to vmap. There's no means of handling dirty status in vmap as there's no
write-only mapping available.

Both flags, _accessed_on_put and _dirty_on_put, have always been part of
the gem-shmem object, but never used much. So most drivers did not track
the page status correctly.

Only the v3d and imagination drivers make limited use of _dirty_on_put. In
the case of imagination, move the flag setting from init to cleanup. This
ensures writeback of modified pages but does not interfere with the
internal vmap/vunmap calls. V3d already implements this behaviour.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> # gem-shmem
Acked-by: Frank Binns <frank.binns@imgtec.com> # imagination
Tested-by: Frank Binns <frank.binns@imgtec.com> # imagination
Link: https://patch.msgid.link/20260227114509.165572-7-tzimmermann@suse.de
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/imagination/pvr_gem.c

index 1ab2bbd3860ca110cc80bad451579d87ad965e22..4500deef41278c9a2ef7a8e8c2751b93bff224eb 100644 (file)
@@ -265,6 +265,8 @@ void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
                                  shmem->pages_mark_dirty_on_put,
                                  shmem->pages_mark_accessed_on_put);
                shmem->pages = NULL;
+               shmem->pages_mark_accessed_on_put = false;
+               shmem->pages_mark_dirty_on_put = false;
        }
 }
 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
@@ -397,6 +399,8 @@ int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,
                } else {
                        iosys_map_set_vaddr(map, shmem->vaddr);
                        refcount_set(&shmem->vmap_use_count, 1);
+                       shmem->pages_mark_accessed_on_put = true;
+                       shmem->pages_mark_dirty_on_put = true;
                }
        }
 
index 686a3fe22986d044440f527659b97503d87d4b1b..d8660d6a8e01b73832dddf7aeaa40aadbe4d4a46 100644 (file)
 
 static void pvr_gem_object_free(struct drm_gem_object *obj)
 {
-       drm_gem_shmem_object_free(obj);
+       struct drm_gem_shmem_object *shmem_obj = to_drm_gem_shmem_obj(obj);
+
+       shmem_obj->pages_mark_dirty_on_put = true;
+       drm_gem_shmem_free(shmem_obj);
 }
 
 static struct dma_buf *pvr_gem_export(struct drm_gem_object *obj, int flags)
@@ -363,7 +366,6 @@ pvr_gem_object_create(struct pvr_device *pvr_dev, size_t size, u64 flags)
        if (IS_ERR(shmem_obj))
                return ERR_CAST(shmem_obj);
 
-       shmem_obj->pages_mark_dirty_on_put = true;
        shmem_obj->map_wc = !(flags & PVR_BO_CPU_CACHED);
        pvr_obj = shmem_gem_to_pvr_gem(shmem_obj);
        pvr_obj->flags = flags;