From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56997221D96 for ; Fri, 3 Apr 2026 07:57:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775203078; cv=none; b=A0xL27otNNLoJzQznn51ZziZkd34oqI0B46Lh4INtf7O9dKbvIcPDuqn5iByEihcQc5nLuUdA4N4fS9Bx9uVv29ZMm5vjtH9SL5VysWqs40GD0apMZKTmCrGtKhAozAK9ykAQJxebwOp4yknE1jU75EG9VxrVX4Ve8/l6uiy2HY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775203078; c=relaxed/simple; bh=YoTFrjLkGAflEy1qRaxjWbCJiKRCH9HY1UiBdJlgevw=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=G+siVqh1pDIn69xiC3jKu+votko9lEIYwrlerY6gGLx8xu7lMhjFw3uNjVrPuBpxQGEajoOsoK+Va4gGYJ9iA8N0gXaD8ZvLKuRQlI7bkuG/piku0aHvnyfQQou2QLhchBNb8i3C55j4byxWPxWNjkKIeAZXc1ZnIa7PD2PxRVA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=nPE8SjAn; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="nPE8SjAn" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1775203075; bh=YoTFrjLkGAflEy1qRaxjWbCJiKRCH9HY1UiBdJlgevw=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=nPE8SjAnEZBbJgABAw3FhSWYZmzKwhs2mme9AMCx9PAn6Cn/Slk4Y4m9Jyg6MlNaP 9e8q0xE8h88QNwZ5b9wcjvXN5W2del+Vsa4dCgVP0SrZE/cOZ3XKxeCNlxbKO4bLDO /RVuh1FR7t67aQstwvfvqPpZ/LkExksNsKpdIRAspq39jm7kJd5cpKWUgjznLImqeA WdSg2FDY6l6rejIBPzI85vgHTvZGzbTQ7x4tAAfsLJ6CDHMjVa9hnMc/OQ5uhc+t/J awcn0oq1k8y8eatl0dhihjtCtGng34XNmZu1bxuaC2vR/2tieG/FKpf1wqvBnFeofM TfrVgpPkB2UxQ== Received: from [IPV6:2a01:e0a:5e3:6100:7aed:fe0e:8590:cbaa] (unknown [IPv6:2a01:e0a:5e3:6100:7aed:fe0e:8590:cbaa]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: loicmolinari) by bali.collaboradmins.com (Postfix) with ESMTPSA id C0BE317E8683; Fri, 3 Apr 2026 09:57:54 +0200 (CEST) Message-ID: <1268c6cf-f3d7-4085-baca-796526125f44@collabora.com> Date: Fri, 3 Apr 2026 09:57:53 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] drm/shmem_helper: Make sure PMD entries get the writeable upgrade To: Boris Brezillon , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , dri-devel@lists.freedesktop.org Cc: David Airlie , Simona Vetter , linux-kernel@vger.kernel.org, Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang , linux-mm@kvack.org, kernel@collabora.com, Biju Das , Tommaso Merciai References: <20260320151914.586945-1-boris.brezillon@collabora.com> Content-Language: fr From: =?UTF-8?Q?Lo=C3=AFc_Molinari?= Organization: Collabora Ltd In-Reply-To: <20260320151914.586945-1-boris.brezillon@collabora.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Boris, On 20/03/2026 16:19, Boris Brezillon wrote: > Unlike PTEs which are automatically upgraded to writeable entries if > .pfn_mkwrite() returns 0, the PMD upgrades go through .huge_fault(), > and we currently pretend to have handled the make-writeable request > even though we only ever map things read-only. Make sure we pass the > proper "write" info to vmf_insert_pfn_pmd() in that case. > > This also means we have to record the mkwrite event in the .huge_fault() > path now. Move the dirty tracking logic to a > drm_gem_shmem_record_mkwrite() helper so it can also be called from > drm_gem_shmem_pfn_mkwrite(). > > Note that this wasn't a problem before commit 28e3918179aa > ("drm/gem-shmem: Track folio accessed/dirty status in mmap"), because > the pgprot were not lowered to read-only before this commit (see the > vma_wants_writenotify() in vma_set_page_prot()). > > Fixes: 28e3918179aa ("drm/gem-shmem: Track folio accessed/dirty status in mmap") > Signed-off-by: Boris Brezillon > Cc: Biju Das > Cc: Thomas Zimmermann > Cc: Tommaso Merciai > --- > > This patch is based on drm-tip [2], because that's the only branch > that has both [1] and the dirty tracking changes that live in > drm-misc-next. > > Also added the THP maintainers in Cc, so I can hopefully get some > feedback on the fix. For instance, I'm still unsure > drm_gem_shmem_pfn_mkwrite() is race-free (do we need some locking > there? should we call folio_mark_dirty_lock()? should we call the > fault handler directly from there and have all the dirty tracking > in this .[huge_]fault path?). > > [1]https://yhbt.net/lore/dri-devel/20260319015224.46896-1-pedrodemargomes@gmail.com/ > [2]https://gitlab.freedesktop.org/drm/tip > --- > drivers/gpu/drm/drm_gem_shmem_helper.c | 46 ++++++++++++++++++-------- > 1 file changed, 32 insertions(+), 14 deletions(-) > > diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c > index 2062ca607833..545933c7f712 100644 > --- a/drivers/gpu/drm/drm_gem_shmem_helper.c > +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c > @@ -554,6 +554,21 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev, > } > EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create); > > +static void drm_gem_shmem_record_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); > + loff_t num_pages = obj->size >> PAGE_SHIFT; > + pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ > + > + if (drm_WARN_ON(obj->dev, !shmem->pages || page_offset >= num_pages)) > + return; > + > + file_update_time(vma->vm_file); > + folio_mark_dirty(page_folio(shmem->pages[page_offset])); Unless we're sure the folio can't be truncated by another CPU, maybe we should use folio_mark_dirty_lock() here. This is what's done for pages (not PFNs) in mm/memory.c. Let's wait and see how it goes without locking for now. Reviewed-by: Loïc Molinari Regards, Loïc > +} > + > static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order, > unsigned long pfn) > { > @@ -566,8 +581,23 @@ static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order, > > if (aligned && > folio_test_pmd_mappable(page_folio(pfn_to_page(pfn)))) { > + vm_fault_t ret; > + > pfn &= PMD_MASK >> PAGE_SHIFT; > - return vmf_insert_pfn_pmd(vmf, pfn, false); > + > + /* Unlike PTEs which are automatically upgraded to > + * writeable entries, the PMD upgrades go through > + * .huge_fault(). Make sure we pass the "write" info > + * along in that case. > + * This also means we have to record the write fault > + * here, instead of in .pfn_mkwrite(). > + */ > + ret = vmf_insert_pfn_pmd(vmf, pfn, > + vmf->flags & FAULT_FLAG_WRITE); > + if (ret == VM_FAULT_NOPAGE && (vmf->flags & FAULT_FLAG_WRITE)) > + drm_gem_shmem_record_mkwrite(vmf); > + > + return ret; > } > #endif > } > @@ -655,19 +685,7 @@ static void drm_gem_shmem_vm_close(struct vm_area_struct *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); > - loff_t num_pages = obj->size >> PAGE_SHIFT; > - pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ > - > - if (drm_WARN_ON(obj->dev, !shmem->pages || page_offset >= num_pages)) > - return VM_FAULT_SIGBUS; > - > - file_update_time(vma->vm_file); > - > - folio_mark_dirty(page_folio(shmem->pages[page_offset])); > - > + drm_gem_shmem_record_mkwrite(vmf); > return 0; > } >