On Mon,  9 Feb 2026 14:27:14 +0100
Thomas Zimmermann <[email protected]> wrote:

> Invoke folio_mark_accessed() in mmap page faults to add the folio to
> the memory manager's LRU list. Userspace invokes mmap to get the memory
> for software rendering. Compositors do the same when creating the final
> on-screen image, so keeping the pages in LRU makes sense. Avoids paging
> out graphics buffers when under memory pressure.
> 
> In pfn_mkwrite, further invoke the folio_mark_dirty() to add the folio
> for writeback should the underlying file be paged out from system memory.
> This rarely happens in practice, yet it would corrupt the buffer content.
> 
> This has little effect on a system's hardware-accelerated rendering, which
> only mmaps for an initial setup of textures, meshes, shaders, etc.
> 
> v3:
> - rewrite for VM_PFNMAP
> v2:
> - adapt to changes in drm_gem_shmem_try_mmap_pmd()
> 
> Signed-off-by: Thomas Zimmermann <[email protected]>
> Reviewed-by: Boris Brezillon <[email protected]>
> ---
>  drivers/gpu/drm/drm_gem_shmem_helper.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
> b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index c3a054899ba3..0c86ad40a049 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -598,6 +598,9 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault 
> *vmf)
>       if (ret != VM_FAULT_NOPAGE)
>               ret = vmf_insert_pfn(vma, vmf->address, pfn);
>  
> +     if (likely(!(ret & VM_FAULT_ERROR)))

Can't we just go

        if (ret == VM_FAULT_NOPAGE)

here?

> +             folio_mark_accessed(folio);
> +
>  out:
>       dma_resv_unlock(obj->resv);
>  
> @@ -638,10 +641,27 @@ static void drm_gem_shmem_vm_close(struct 
> vm_area_struct *vma)
>       drm_gem_vm_close(vma);
>  }
>  
> +static vm_fault_t drm_gem_shmem_pfn_mkwrite(struct vm_fault *vmf)
> +{
> +     struct vm_area_struct *vma = vmf->vma;
> +     struct drm_gem_object *obj = vma->vm_private_data;
> +     struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
> +     pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within 
> VMA */
> +     struct page *page = shmem->pages[page_offset];

Should we have a

        if (WARN_ON(!shmem->pages ||
                    page_offset <= (obj->size >> PAGE_SHIFT)))
                return VM_FAULT_SIGBUS;


?

> +     struct folio *folio = page_folio(page);
> +
> +     file_update_time(vma->vm_file);
> +
> +     folio_mark_dirty(folio);
> +
> +     return 0;
> +}
> +
>  const struct vm_operations_struct drm_gem_shmem_vm_ops = {
>       .fault = drm_gem_shmem_fault,
>       .open = drm_gem_shmem_vm_open,
>       .close = drm_gem_shmem_vm_close,
> +     .pfn_mkwrite = drm_gem_shmem_pfn_mkwrite,
>  };
>  EXPORT_SYMBOL_GPL(drm_gem_shmem_vm_ops);
>  

Reply via email to