[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251220040446.274991-5-houtao@huaweicloud.com>
Date: Sat, 20 Dec 2025 12:04:37 +0800
From: Hou Tao <houtao@...weicloud.com>
To: linux-kernel@...r.kernel.org
Cc: linux-pci@...r.kernel.org,
linux-mm@...ck.org,
linux-nvme@...ts.infradead.org,
Bjorn Helgaas <bhelgaas@...gle.com>,
Logan Gunthorpe <logang@...tatee.com>,
Alistair Popple <apopple@...dia.com>,
Leon Romanovsky <leonro@...dia.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Tejun Heo <tj@...nel.org>,
"Rafael J . Wysocki" <rafael@...nel.org>,
Danilo Krummrich <dakr@...nel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
David Hildenbrand <david@...nel.org>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>,
Keith Busch <kbusch@...nel.org>,
Jens Axboe <axboe@...nel.dk>,
Christoph Hellwig <hch@....de>,
Sagi Grimberg <sagi@...mberg.me>,
houtao1@...wei.com
Subject: [PATCH 04/13] kernfs: add support for may_split and pagesize callbacks
From: Hou Tao <houtao1@...wei.com>
->may_split() and ->pagesize() callbacks are necessary for the support
of compound page. ->may_split() will check whether the splitting of
compound page is allowed during mprotect or remap, and ->pagesize() will
output the correct page size in /proc/${pid}/smap file. These two
callbacks will be used by the following patch to enable the mapping of
compound page of p2pdma memory into userspace, therefore, add the
support for these two callbacks.
Signed-off-by: Hou Tao <houtao1@...wei.com>
---
fs/kernfs/file.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 9773b5734a2c..5df45b1dbb36 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -384,6 +384,46 @@ static void kernfs_vma_open(struct vm_area_struct *vma)
kernfs_put_active_of(of);
}
+static int kernfs_vma_may_split(struct vm_area_struct *vma, unsigned long addr)
+{
+ struct file *file = vma->vm_file;
+ struct kernfs_open_file *of = kernfs_of(file);
+ int ret;
+
+ if (!of->vm_ops)
+ return 0;
+
+ if (!kernfs_get_active_of(of))
+ return -ENODEV;
+
+ ret = 0;
+ if (of->vm_ops->may_split)
+ ret = of->vm_ops->may_split(vma, addr);
+
+ kernfs_put_active_of(of);
+ return ret;
+}
+
+static unsigned long kernfs_vma_pagesize(struct vm_area_struct *vma)
+{
+ struct file *file = vma->vm_file;
+ struct kernfs_open_file *of = kernfs_of(file);
+ unsigned long size;
+
+ if (!of->vm_ops)
+ return PAGE_SIZE;
+
+ if (!kernfs_get_active_of(of))
+ return PAGE_SIZE;
+
+ size = PAGE_SIZE;
+ if (of->vm_ops->pagesize)
+ size = of->vm_ops->pagesize(vma);
+
+ kernfs_put_active_of(of);
+ return size;
+}
+
static vm_fault_t kernfs_vma_fault(struct vm_fault *vmf)
{
struct file *file = vmf->vma->vm_file;
@@ -449,9 +489,11 @@ static int kernfs_vma_access(struct vm_area_struct *vma, unsigned long addr,
static const struct vm_operations_struct kernfs_vm_ops = {
.open = kernfs_vma_open,
+ .may_split = kernfs_vma_may_split,
.fault = kernfs_vma_fault,
.page_mkwrite = kernfs_vma_page_mkwrite,
.access = kernfs_vma_access,
+ .pagesize = kernfs_vma_pagesize,
};
static unsigned long kernfs_get_unmapped_area(struct file *file, unsigned long uaddr,
--
2.29.2
Powered by blists - more mailing lists