* [PATCH 0/8] drm: Optimize page tables overhead with THP
@ 2025-09-29 20:03 Loïc Molinari
2025-09-29 20:03 ` [PATCH 1/8] drm/shmem-helper: Add huge page fault handler Loïc Molinari
` (7 more replies)
0 siblings, 8 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
This series aims to reduce the page tables overhead of DRM drivers for
builds with CONFIG_TRANSPARENT_HUGEPAGE enabled and either the sysfs
config '/sys/kernel/mm/transparent_hugepage/shmem_enabled'
appropriately set or drivers using a dedicated huge tmpfs mount point.
It starts by adding a huge page fault handler for GEM objects to
insert PMD or PUD mappings whenever the shmem backing store manages to
create huge folios. It then introduces a dedicated get_unmapped_area
file operation on the DRM file descriptor for GEM objects to get the
best virtual address alignment for the underlying shmem buffers.
The remaining commits propose shmem helpers to create and release huge
tmpfs mount points and adapt the i915 and V3D drivers. The helpers are
then used to optionally enable Transparent Hugepage for Panfrost and
Panthor.
Loïc Molinari (8):
drm/shmem-helper: Add huge page fault handler
drm/gem: Introduce drm_gem_get_unmapped_area() fop
drm/shmem-helper: Add huge tmpfs mount point helpers
drm/i915: Use huge tmpfs mount point helpers
drm/v3d: Use huge tmpfs mount point helpers
drm/panthor: Introduce huge tmpfs mount point option
drm/panthor: Improve IOMMU map/unmap debugging logs
drm/panfrost: Introduce huge tmpfs mount point option
drivers/gpu/drm/drm_gem.c | 110 ++++++++++++++++----
drivers/gpu/drm/drm_gem_shmem_helper.c | 112 ++++++++++++++++++++-
drivers/gpu/drm/i915/gem/i915_gemfs.c | 33 +-----
drivers/gpu/drm/panfrost/panfrost_device.c | 4 +
drivers/gpu/drm/panfrost/panfrost_device.h | 2 +
drivers/gpu/drm/panfrost/panfrost_drv.c | 6 ++
drivers/gpu/drm/panfrost/panfrost_drv.h | 11 ++
drivers/gpu/drm/panfrost/panfrost_gem.c | 29 +++++-
drivers/gpu/drm/panfrost/panfrost_gem.h | 3 +
drivers/gpu/drm/panthor/panthor_device.c | 4 +
drivers/gpu/drm/panthor/panthor_device.h | 3 +
drivers/gpu/drm/panthor/panthor_drv.c | 7 ++
drivers/gpu/drm/panthor/panthor_drv.h | 11 ++
drivers/gpu/drm/panthor/panthor_gem.c | 30 +++++-
drivers/gpu/drm/panthor/panthor_gem.h | 3 +
drivers/gpu/drm/panthor/panthor_mmu.c | 19 +++-
drivers/gpu/drm/v3d/v3d_gemfs.c | 31 +-----
include/drm/drm_gem.h | 4 +
include/drm/drm_gem_shmem_helper.h | 14 +++
mm/shmem.c | 1 +
20 files changed, 346 insertions(+), 91 deletions(-)
create mode 100644 drivers/gpu/drm/panfrost/panfrost_drv.h
create mode 100644 drivers/gpu/drm/panthor/panthor_drv.h
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/8] drm/shmem-helper: Add huge page fault handler
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-29 20:03 ` [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop Loïc Molinari
` (6 subsequent siblings)
7 siblings, 0 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
This gives the mm subsystem the ability to propose the insertion of
PUD or PMD-sized mappings for the faulting addresses.
On builds with CONFIG_TRANSPARENT_HUGEPAGE enabled, if the mmap() user
address is aligned to a huge page size, if the GEM object is backed by
shmem buffers on mount points setting the 'huge=' option and if the
shmem backing store manages to allocate a huge folio, the CPU mapping
will then benefit from significantly increased memcpy() performance.
When these conditions are met on a system with 2 MiB huge pages, an
aligned copy of 2 MiB would raise a single page fault instead of 4096.
v2:
- set ret to VM_FAULT_FALLBACK in default switch statement
- ifdef out paddr declaration
- improve commit message
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
---
drivers/gpu/drm/drm_gem_shmem_helper.c | 56 ++++++++++++++++++++++++--
1 file changed, 52 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 50594cf8e17c..22c4b09e10a3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -573,7 +573,8 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
}
EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create);
-static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
+static vm_fault_t drm_gem_shmem_huge_fault(struct vm_fault *vmf,
+ unsigned int order)
{
struct vm_area_struct *vma = vmf->vma;
struct drm_gem_object *obj = vma->vm_private_data;
@@ -582,6 +583,10 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
vm_fault_t ret;
struct page *page;
pgoff_t page_offset;
+ unsigned long pfn;
+#if defined(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP) || defined(CONFIG_ARCH_SUPPORTS_PUD_PFNMAP)
+ unsigned long paddr;
+#endif
/* We don't use vmf->pgoff since that has the fake offset */
page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
@@ -592,17 +597,57 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
drm_WARN_ON_ONCE(obj->dev, !shmem->pages) ||
shmem->madv < 0) {
ret = VM_FAULT_SIGBUS;
- } else {
- page = shmem->pages[page_offset];
+ goto out;
+ }
- ret = vmf_insert_pfn(vma, vmf->address, page_to_pfn(page));
+ page = shmem->pages[page_offset];
+ pfn = page_to_pfn(page);
+
+ switch (order) {
+ case 0:
+ ret = vmf_insert_pfn(vma, vmf->address, pfn);
+ break;
+
+#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
+ case PMD_ORDER:
+ paddr = pfn << PAGE_SHIFT;
+ if (((vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK)) &&
+ (folio_order(page_folio(page)) == PMD_ORDER))
+ ret = vmf_insert_pfn_pmd(
+ vmf, pfn & (PMD_MASK >> PAGE_SHIFT), false);
+ else
+ ret = VM_FAULT_FALLBACK;
+ break;
+#endif
+
+#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
+ case PUD_ORDER:
+ paddr = pfn << PAGE_SHIFT;
+ if (((vmf->address & ~PUD_MASK) == (paddr & ~PUD_MASK)) &&
+ (folio_order(page_folio(page)) == PUD_ORDER))
+ ret = vmf_insert_pfn_pud(
+ vmf, pfn & (PUD_MASK >> PAGE_SHIFT), false);
+ else
+ ret = VM_FAULT_FALLBACK;
+ break;
+#endif
+
+ default:
+ ret = VM_FAULT_FALLBACK;
+ break;
}
+ out:
dma_resv_unlock(shmem->base.resv);
return ret;
}
+static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
+{
+ return drm_gem_shmem_huge_fault(vmf, 0);
+}
+
static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
{
struct drm_gem_object *obj = vma->vm_private_data;
@@ -639,6 +684,9 @@ static void drm_gem_shmem_vm_close(struct vm_area_struct *vma)
const struct vm_operations_struct drm_gem_shmem_vm_ops = {
.fault = drm_gem_shmem_fault,
+#if defined(CONFIG_ARCH_SUPPORTS_PMD_PFNMAP) || defined(CONFIG_ARCH_SUPPORTS_PUD_PFNMAP)
+ .huge_fault = drm_gem_shmem_huge_fault,
+#endif
.open = drm_gem_shmem_vm_open,
.close = drm_gem_shmem_vm_close,
};
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
2025-09-29 20:03 ` [PATCH 1/8] drm/shmem-helper: Add huge page fault handler Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-30 10:05 ` kernel test robot
2025-09-30 10:30 ` Boris Brezillon
2025-09-29 20:03 ` [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers Loïc Molinari
` (5 subsequent siblings)
7 siblings, 2 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
mmap() calls on the drm file pointer currently always end up using
mm_get_unmapped_area() to get a free mapping region. On builds with
CONFIG_TRANSPARENT_HUGEPAGE enabled, this isn't ideal for GEM objects
backed by shmem buffers on mount points setting the 'huge=' option
because it can't correctly figure out the potentially huge address
alignment required.
This commit introduces the drm_gem_get_unmapped_area() function which
is meant to be used as a get_unmapped_area file operation on the drm
file pointer to lookup GEM objects based on their fake offsets and get
a properly aligned region by calling shmem_get_unmapped_area() with
the right file pointer. If a GEM object isn't available at the given
offset or if the caller isn't granted access to it, the function falls
back to mm_get_unmapped_area().
This also makes drm_gem_get_unmapped_area() part of the default GEM
file operations so that all the drm drivers can benefit from more
efficient mappings thanks to the huge page fault handler introduced in
previous commit 'drm/shmem-helper: Add huge page fault handler'.
The shmem_get_unmapped_area() function needs to be exported so that
it can be used from the drm subsystem.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/drm_gem.c | 110 ++++++++++++++++++++++++++++++--------
include/drm/drm_gem.h | 4 ++
mm/shmem.c | 1 +
3 files changed, 93 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index cbeb76b2124f..d027db462c2d 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1187,36 +1187,27 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
}
EXPORT_SYMBOL(drm_gem_mmap_obj);
-/**
- * drm_gem_mmap - memory map routine for GEM objects
- * @filp: DRM file pointer
- * @vma: VMA for the area to be mapped
- *
- * If a driver supports GEM object mapping, mmap calls on the DRM file
- * descriptor will end up here.
- *
- * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
- * contain the fake offset we created when the GTT map ioctl was called on
- * the object) and map it with a call to drm_gem_mmap_obj().
- *
- * If the caller is not granted access to the buffer object, the mmap will fail
- * with EACCES. Please see the vma manager for more information.
+/*
+ * Look up a GEM object in offset space based on the exact start address. The
+ * caller must be granted access to the object. Returns a GEM object on success
+ * or a negative error code on failure. The returned GEM object needs to be
+ * released with drm_gem_object_put().
*/
-int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+static struct drm_gem_object *
+drm_gem_object_lookup_from_offset(struct file *filp, unsigned long start,
+ unsigned long pages)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_gem_object *obj = NULL;
struct drm_vma_offset_node *node;
- int ret;
if (drm_dev_is_unplugged(dev))
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
drm_vma_offset_lock_lookup(dev->vma_offset_manager);
node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
- vma->vm_pgoff,
- vma_pages(vma));
+ start, pages);
if (likely(node)) {
obj = container_of(node, struct drm_gem_object, vma_node);
/*
@@ -1235,14 +1226,89 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
if (!obj)
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
if (!drm_vma_node_is_allowed(node, priv)) {
drm_gem_object_put(obj);
- return -EACCES;
+ return ERR_PTR(-EACCES);
}
- ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT,
+ return obj;
+}
+
+/**
+ * drm_gem_get_unmapped_area - get memory mapping region routine for GEM objects
+ * @filp: DRM file pointer
+ * @uaddr: User address hint
+ * @len: Mapping length
+ * @pgoff: Offset (in pages)
+ * @flags: Mapping flags
+ *
+ * If a driver supports GEM object mapping, before ending up in drm_gem_mmap(),
+ * mmap calls on the DRM file descriptor will first try to find a free linear
+ * address space large enough for a mapping. Since GEM objects are backed by
+ * shmem buffers, this should preferably be handled by the shmem virtual memory
+ * filesystem which can appropriately align addresses to huge page sizes when
+ * needed.
+ *
+ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
+ * contain the fake offset we created) and call shmem_get_unmapped_area() with
+ * the right file pointer.
+ *
+ * If a GEM object is not available at the given offset or if the caller is not
+ * granted access to it, fall back to mm_get_unmapped_area().
+ */
+unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ struct drm_gem_object *obj;
+ unsigned long ret;
+
+ obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
+ if (IS_ERR(obj))
+ return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
+ flags);
+
+ ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
+
+ drm_gem_object_put(obj);
+
+ return ret;
+#else
+ return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
+#endif
+}
+EXPORT_SYMBOL(drm_gem_get_unmapped_area);
+
+/**
+ * drm_gem_mmap - memory map routine for GEM objects
+ * @filp: DRM file pointer
+ * @vma: VMA for the area to be mapped
+ *
+ * If a driver supports GEM object mapping, mmap calls on the DRM file
+ * descriptor will end up here.
+ *
+ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
+ * contain the fake offset we created) and map it with a call to
+ * drm_gem_mmap_obj().
+ *
+ * If the caller is not granted access to the buffer object, the mmap will fail
+ * with EACCES. Please see the vma manager for more information.
+ */
+int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_gem_object *obj;
+ int ret;
+
+ obj = drm_gem_object_lookup_from_offset(filp, vma->vm_pgoff,
+ vma_pages(vma));
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+
+ ret = drm_gem_mmap_obj(obj,
+ drm_vma_node_size(&obj->vma_node) << PAGE_SHIFT,
vma);
drm_gem_object_put(obj);
diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
index 8d48d2af2649..7c8bd67d087c 100644
--- a/include/drm/drm_gem.h
+++ b/include/drm/drm_gem.h
@@ -469,6 +469,7 @@ struct drm_gem_object {
.poll = drm_poll,\
.read = drm_read,\
.llseek = noop_llseek,\
+ .get_unmapped_area = drm_gem_get_unmapped_area,\
.mmap = drm_gem_mmap, \
.fop_flags = FOP_UNSIGNED_OFFSET
@@ -506,6 +507,9 @@ void drm_gem_vm_close(struct vm_area_struct *vma);
int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
struct vm_area_struct *vma);
int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
+ unsigned long len, unsigned long pgoff,
+ unsigned long flags);
/**
* drm_gem_object_get - acquire a GEM buffer object reference
diff --git a/mm/shmem.c b/mm/shmem.c
index e2c76a30802b..b2f41b430daa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2915,6 +2915,7 @@ unsigned long shmem_get_unmapped_area(struct file *file,
return addr;
return inflated_addr;
}
+EXPORT_SYMBOL_GPL(shmem_get_unmapped_area);
#ifdef CONFIG_NUMA
static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *mpol)
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
2025-09-29 20:03 ` [PATCH 1/8] drm/shmem-helper: Add huge page fault handler Loïc Molinari
2025-09-29 20:03 ` [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-30 10:57 ` Boris Brezillon
2025-09-29 20:03 ` [PATCH 4/8] drm/i915: Use " Loïc Molinari
` (4 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Add the drm_gem_shmem_helper_huge_mnt_create() and
drm_gem_shmem_helper_huge_mnt_free() helpers to avoid code duplication
in the i915 and v3d drivers (and soon panfrost/panthor).
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/drm_gem_shmem_helper.c | 56 ++++++++++++++++++++++++++
include/drm/drm_gem_shmem_helper.h | 14 +++++++
2 files changed, 70 insertions(+)
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index 22c4b09e10a3..808721b8be3e 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -5,7 +5,9 @@
#include <linux/dma-buf.h>
#include <linux/export.h>
+#include <linux/fs_context.h>
#include <linux/module.h>
+#include <linux/mount.h>
#include <linux/mutex.h>
#include <linux/shmem_fs.h>
#include <linux/slab.h>
@@ -36,6 +38,60 @@ MODULE_IMPORT_NS("DMA_BUF");
* drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
*/
+static int drm_gem_shmem_add_fc_param(struct fs_context *fc, const char *key,
+ const char *value)
+{
+ return vfs_parse_fs_string(fc, key, value, strlen(value));
+}
+
+/**
+ * drm_gem_shmem_huge_mnt_create - Create a huge tmpfs mountpoint
+ * @value: huge tmpfs mount option value
+ *
+ * This function creates and mounts an internal huge tmpfs mountpoint for use
+ * with the drm_gem_shmem_create_with_mnt() function.
+ *
+ * The most common option value is "within_size" which only allocates huge pages
+ * if the page will be fully within the GEM object size. "always", "advise" and
+ * "never" are supported too but the latter would just create a mountpoint
+ * similar to default "shm_mnt" one. See shmemfs and Transparent Hugepage for
+ * more information.
+ *
+ * Returns:
+ * A struct vfsmount * on success or an ERR_PTR()-encoded negative error code on
+ * failure.
+ */
+struct vfsmount *drm_gem_shmem_huge_mnt_create(const char *value)
+{
+ struct file_system_type *type;
+ struct fs_context *fc;
+ struct vfsmount *mnt;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
+ return ERR_PTR(-EOPNOTSUPP);
+
+ type = get_fs_type("tmpfs");
+ if (!type)
+ return ERR_PTR(-EOPNOTSUPP);
+
+ fc = fs_context_for_mount(type, SB_KERNMOUNT);
+ if (IS_ERR(fc))
+ return ERR_CAST(fc);
+ ret = drm_gem_shmem_add_fc_param(fc, "source", "tmpfs");
+ if (ret)
+ return ERR_PTR(-ENOPARAM);
+ ret = drm_gem_shmem_add_fc_param(fc, "huge", value);
+ if (ret)
+ return ERR_PTR(-ENOPARAM);
+
+ mnt = fc_mount_longterm(fc);
+ put_fs_context(fc);
+
+ return mnt;
+}
+EXPORT_SYMBOL_GPL(drm_gem_shmem_huge_mnt_create);
+
static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
.free = drm_gem_shmem_object_free,
.print_info = drm_gem_shmem_object_print_info,
diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
index 589f7bfe7506..5e153fb63f38 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -107,6 +107,20 @@ struct drm_gem_shmem_object {
#define to_drm_gem_shmem_obj(obj) \
container_of(obj, struct drm_gem_shmem_object, base)
+struct vfsmount *drm_gem_shmem_huge_mnt_create(const char *value);
+
+/**
+ * drm_gem_shmem_huge_mnt_free - Release a huge tmpfs mountpoint.
+ * @mnt: struct vfsmount * to release
+ *
+ * This function unmounts and releases an internal huge tmpfs mountpoint. If
+ * @mnt is NULL, no operation is performed.
+ */
+static inline void drm_gem_shmem_huge_mnt_free(struct vfsmount *mnt)
+{
+ kern_unmount(mnt);
+}
+
int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size);
struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 4/8] drm/i915: Use huge tmpfs mount point helpers
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
` (2 preceding siblings ...)
2025-09-29 20:03 ` [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-30 11:06 ` kernel test robot
2025-09-29 20:03 ` [PATCH 5/8] drm/v3d: " Loïc Molinari
` (3 subsequent siblings)
7 siblings, 1 reply; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Make use of the new drm_gem_shmem_huge_mnt_create() and
drm_gem_shmem_huge_mnt_free() helpers to avoid code duplication.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/i915/gem/i915_gemfs.c | 33 +++------------------------
1 file changed, 3 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gemfs.c b/drivers/gpu/drm/i915/gem/i915_gemfs.c
index a09e2eb47175..70563a6a0b81 100644
--- a/drivers/gpu/drm/i915/gem/i915_gemfs.c
+++ b/drivers/gpu/drm/i915/gem/i915_gemfs.c
@@ -3,25 +3,13 @@
* Copyright © 2017 Intel Corporation
*/
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/fs_context.h>
-
#include "i915_drv.h"
#include "i915_gemfs.h"
#include "i915_utils.h"
-static int add_param(struct fs_context *fc, const char *key, const char *val)
-{
- return vfs_parse_fs_string(fc, key, val, strlen(val));
-}
-
void i915_gemfs_init(struct drm_i915_private *i915)
{
- struct file_system_type *type;
- struct fs_context *fc;
struct vfsmount *gemfs;
- int ret;
/*
* By creating our own shmemfs mountpoint, we can pass in
@@ -38,23 +26,8 @@ void i915_gemfs_init(struct drm_i915_private *i915)
if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915))
return;
- if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
- goto err;
-
- type = get_fs_type("tmpfs");
- if (!type)
- goto err;
-
- fc = fs_context_for_mount(type, SB_KERNMOUNT);
- if (IS_ERR(fc))
- goto err;
- ret = add_param(fc, "source", "tmpfs");
- if (!ret)
- ret = add_param(fc, "huge", "within_size");
- if (!ret)
- gemfs = fc_mount_longterm(fc);
- put_fs_context(fc);
- if (ret)
+ gemfs = drm_gem_shmem_huge_mnt_create("within_size");
+ if (IS_ERR(gemfs))
goto err;
i915->mm.gemfs = gemfs;
@@ -70,5 +43,5 @@ void i915_gemfs_init(struct drm_i915_private *i915)
void i915_gemfs_fini(struct drm_i915_private *i915)
{
- kern_unmount(i915->mm.gemfs);
+ drm_gem_shmem_huge_mnt_free(i915->mm.gemfs);
}
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 5/8] drm/v3d: Use huge tmpfs mount point helpers
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
` (3 preceding siblings ...)
2025-09-29 20:03 ` [PATCH 4/8] drm/i915: Use " Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-29 20:03 ` [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option Loïc Molinari
` (2 subsequent siblings)
7 siblings, 0 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Make use of the new drm_gem_shmem_huge_mnt_create() and
drm_gem_shmem_huge_mnt_free() helpers to avoid code duplication.
drm_gem_shmem_huge_mnt_free() handles NULL pointers.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/v3d/v3d_gemfs.c | 31 +++----------------------------
1 file changed, 3 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_gemfs.c b/drivers/gpu/drm/v3d/v3d_gemfs.c
index 8ec6ed82b3d9..f54705dba217 100644
--- a/drivers/gpu/drm/v3d/v3d_gemfs.c
+++ b/drivers/gpu/drm/v3d/v3d_gemfs.c
@@ -1,23 +1,11 @@
// SPDX-License-Identifier: GPL-2.0+
/* Copyright (C) 2024 Raspberry Pi */
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/fs_context.h>
-
#include "v3d_drv.h"
-static int add_param(struct fs_context *fc, const char *key, const char *val)
-{
- return vfs_parse_fs_string(fc, key, val, strlen(val));
-}
-
void v3d_gemfs_init(struct v3d_dev *v3d)
{
- struct file_system_type *type;
- struct fs_context *fc;
struct vfsmount *gemfs;
- int ret;
/*
* By creating our own shmemfs mountpoint, we can pass in
@@ -31,20 +19,8 @@ void v3d_gemfs_init(struct v3d_dev *v3d)
if (!super_pages)
goto err;
- type = get_fs_type("tmpfs");
- if (!type)
- goto err;
-
- fc = fs_context_for_mount(type, SB_KERNMOUNT);
- if (IS_ERR(fc))
- goto err;
- ret = add_param(fc, "source", "tmpfs");
- if (!ret)
- ret = add_param(fc, "huge", "within_size");
- if (!ret)
- gemfs = fc_mount_longterm(fc);
- put_fs_context(fc);
- if (ret)
+ gemfs = drm_gem_shmem_huge_mnt_create("within_size");
+ if (IS_ERR(gemfs))
goto err;
v3d->gemfs = gemfs;
@@ -60,6 +36,5 @@ void v3d_gemfs_init(struct v3d_dev *v3d)
void v3d_gemfs_fini(struct v3d_dev *v3d)
{
- if (v3d->gemfs)
- kern_unmount(v3d->gemfs);
+ drm_gem_shmem_huge_mnt_free(v3d->gemfs);
}
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
` (4 preceding siblings ...)
2025-09-29 20:03 ` [PATCH 5/8] drm/v3d: " Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-30 10:34 ` Boris Brezillon
2025-09-30 10:36 ` kernel test robot
2025-09-29 20:03 ` [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs Loïc Molinari
2025-09-29 20:03 ` [PATCH 8/8] drm/panfrost: Introduce huge tmpfs mount point option Loïc Molinari
7 siblings, 2 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Introduce the 'panthor.transparent_hugepage' boolean module parameter
(false by default). When the parameter is set to true, a new tmpfs
mount point is created and mounted using the 'huge=within_size'
option. It's then used at GEM object creation instead of the default
'shm_mnt' mount point in order to enable Transparent Hugepage (THP)
for the object (without having to rely on a system wide parameter).
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/panthor/panthor_device.c | 4 ++++
drivers/gpu/drm/panthor/panthor_device.h | 3 +++
drivers/gpu/drm/panthor/panthor_drv.c | 7 ++++++
drivers/gpu/drm/panthor/panthor_drv.h | 11 +++++++++
drivers/gpu/drm/panthor/panthor_gem.c | 30 +++++++++++++++++++++++-
drivers/gpu/drm/panthor/panthor_gem.h | 3 +++
6 files changed, 57 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/panthor/panthor_drv.h
diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
index 81df49880bd8..4f254b574287 100644
--- a/drivers/gpu/drm/panthor/panthor_device.c
+++ b/drivers/gpu/drm/panthor/panthor_device.c
@@ -17,6 +17,7 @@
#include "panthor_devfreq.h"
#include "panthor_device.h"
#include "panthor_fw.h"
+#include "panthor_gem.h"
#include "panthor_gpu.h"
#include "panthor_hw.h"
#include "panthor_mmu.h"
@@ -98,6 +99,7 @@ void panthor_device_unplug(struct panthor_device *ptdev)
/* Now, try to cleanly shutdown the GPU before the device resources
* get reclaimed.
*/
+ panthor_gem_fini(ptdev);
panthor_sched_unplug(ptdev);
panthor_fw_unplug(ptdev);
panthor_mmu_unplug(ptdev);
@@ -269,6 +271,8 @@ int panthor_device_init(struct panthor_device *ptdev)
if (ret)
goto err_unplug_fw;
+ panthor_gem_init(ptdev);
+
/* ~3 frames */
pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50);
pm_runtime_use_autosuspend(ptdev->base.dev);
diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
index 4fc7cf2aeed5..54ca61567426 100644
--- a/drivers/gpu/drm/panthor/panthor_device.h
+++ b/drivers/gpu/drm/panthor/panthor_device.h
@@ -135,6 +135,9 @@ struct panthor_device {
/** @devfreq: Device frequency scaling management data. */
struct panthor_devfreq *devfreq;
+ /** @huge_mnt: tmpfs mount point with Transparent Hugepage enabled. */
+ struct vfsmount *huge_mnt;
+
/** @unplug: Device unplug related fields. */
struct {
/** @lock: Lock used to serialize unplug operations. */
diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
index fdbe89ef7f43..a2be3b904ca2 100644
--- a/drivers/gpu/drm/panthor/panthor_drv.c
+++ b/drivers/gpu/drm/panthor/panthor_drv.c
@@ -1556,6 +1556,7 @@ static const struct file_operations panthor_drm_driver_fops = {
.read = drm_read,
.llseek = noop_llseek,
.mmap = panthor_mmap,
+ .get_unmapped_area = drm_gem_get_unmapped_area,
.show_fdinfo = drm_show_fdinfo,
.fop_flags = FOP_UNSIGNED_OFFSET,
};
@@ -1623,6 +1624,12 @@ static const struct drm_driver panthor_drm_driver = {
#endif
};
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+bool panthor_transparent_hugepage;
+module_param_named(transparent_hugepage, panthor_transparent_hugepage, bool, 0400);
+MODULE_PARM_DESC(transparent_hugepage, "Use a dedicated tmpfs mount point with Transparent Hugepage enabled (false = default)");
+#endif
+
static int panthor_probe(struct platform_device *pdev)
{
struct panthor_device *ptdev;
diff --git a/drivers/gpu/drm/panthor/panthor_drv.h b/drivers/gpu/drm/panthor/panthor_drv.h
new file mode 100644
index 000000000000..27fe9b6f77bd
--- /dev/null
+++ b/drivers/gpu/drm/panthor/panthor_drv.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
+
+#ifndef __PANTHOR_DRV_H__
+#define __PANTHOR_DRV_H__
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern bool panthor_transparent_hugepage;
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
index 156c7a0b62a2..16916e0b6d89 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.c
+++ b/drivers/gpu/drm/panthor/panthor_gem.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0 or MIT
/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
/* Copyright 2023 Collabora ltd. */
+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
#include <linux/cleanup.h>
#include <linux/dma-buf.h>
@@ -11,10 +12,35 @@
#include <drm/panthor_drm.h>
#include "panthor_device.h"
+#include "panthor_drv.h"
#include "panthor_fw.h"
#include "panthor_gem.h"
#include "panthor_mmu.h"
+void panthor_gem_init(struct panthor_device *ptdev)
+{
+ struct vfsmount *huge_mnt;
+
+ if (!panthor_transparent_hugepage)
+ return;
+
+ huge_mnt = drm_gem_shmem_huge_mnt_create("within_size");
+ if (IS_ERR(huge_mnt)) {
+ drm_warn(&ptdev->base, "Can't use Transparent Hugepage (%ld)\n",
+ PTR_ERR(huge_mnt));
+ return;
+ }
+
+ ptdev->huge_mnt = huge_mnt;
+
+ drm_info(&ptdev->base, "Using Transparent Hugepage\n");
+}
+
+void panthor_gem_fini(struct panthor_device *ptdev)
+{
+ drm_gem_shmem_huge_mnt_free(ptdev->huge_mnt);
+}
+
#ifdef CONFIG_DEBUG_FS
static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo)
{
@@ -270,10 +296,12 @@ panthor_gem_create_with_handle(struct drm_file *file,
u64 *size, u32 flags, u32 *handle)
{
int ret;
+ struct panthor_device *ptdev =
+ container_of(ddev, struct panthor_device, base);
struct drm_gem_shmem_object *shmem;
struct panthor_gem_object *bo;
- shmem = drm_gem_shmem_create(ddev, *size);
+ shmem = drm_gem_shmem_create_with_mnt(ddev, *size, ptdev->huge_mnt);
if (IS_ERR(shmem))
return PTR_ERR(shmem);
diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
index 80c6e24112d0..6804b3912cc2 100644
--- a/drivers/gpu/drm/panthor/panthor_gem.h
+++ b/drivers/gpu/drm/panthor/panthor_gem.h
@@ -136,6 +136,9 @@ struct panthor_gem_object *to_panthor_bo(struct drm_gem_object *obj)
return container_of(to_drm_gem_shmem_obj(obj), struct panthor_gem_object, base);
}
+void panthor_gem_init(struct panthor_device *ptdev);
+void panthor_gem_fini(struct panthor_device *ptdev);
+
struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t size);
int
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
` (5 preceding siblings ...)
2025-09-29 20:03 ` [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
2025-09-30 10:37 ` Boris Brezillon
2025-09-29 20:03 ` [PATCH 8/8] drm/panfrost: Introduce huge tmpfs mount point option Loïc Molinari
7 siblings, 1 reply; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Log the number of pages and their sizes actually mapped/unmapped by
the IOMMU page table driver. Since a map/unmap op is often split in
several ops depending on the underlying scatter/gather table, add the
start address and the total size to the debugging logs in order to
help understand which batch an op is part of.
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/panthor/panthor_mmu.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
index 6dec4354e378..aefbd83d1a75 100644
--- a/drivers/gpu/drm/panthor/panthor_mmu.c
+++ b/drivers/gpu/drm/panthor/panthor_mmu.c
@@ -917,10 +917,9 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
{
struct panthor_device *ptdev = vm->ptdev;
struct io_pgtable_ops *ops = vm->pgtbl_ops;
+ u64 start_iova = iova;
u64 offset = 0;
- drm_dbg(&ptdev->base, "unmap: as=%d, iova=%llx, len=%llx", vm->as.id, iova, size);
-
while (offset < size) {
size_t unmapped_sz = 0, pgcount;
size_t pgsize = get_pgsize(iova + offset, size - offset, &pgcount);
@@ -935,6 +934,12 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
panthor_vm_flush_range(vm, iova, offset + unmapped_sz);
return -EINVAL;
}
+
+ drm_dbg(&ptdev->base,
+ "unmap: as=%d, iova=0x%llx, sz=%llu, va=0x%llx, pgcnt=%zu, pgsz=%zu",
+ vm->as.id, start_iova, size, iova + offset,
+ unmapped_sz / pgsize, pgsize);
+
offset += unmapped_sz;
}
@@ -950,6 +955,7 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot,
struct scatterlist *sgl;
struct io_pgtable_ops *ops = vm->pgtbl_ops;
u64 start_iova = iova;
+ u64 start_size = size;
int ret;
if (!size)
@@ -969,15 +975,18 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot,
len = min_t(size_t, len, size);
size -= len;
- drm_dbg(&ptdev->base, "map: as=%d, iova=%llx, paddr=%pad, len=%zx",
- vm->as.id, iova, &paddr, len);
-
while (len) {
size_t pgcount, mapped = 0;
size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
ret = ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
GFP_KERNEL, &mapped);
+
+ drm_dbg(&ptdev->base,
+ "map: as=%d, iova=0x%llx, sz=%llu, va=0x%llx, pa=%pad, pgcnt=%zu, pgsz=%zu",
+ vm->as.id, start_iova, start_size, iova, &paddr,
+ mapped / pgsize, pgsize);
+
iova += mapped;
paddr += mapped;
len -= mapped;
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 8/8] drm/panfrost: Introduce huge tmpfs mount point option
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
` (6 preceding siblings ...)
2025-09-29 20:03 ` [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs Loïc Molinari
@ 2025-09-29 20:03 ` Loïc Molinari
7 siblings, 0 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-29 20:03 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon, Rob Herring,
Steven Price, Liviu Dudau, Melissa Wen, Maíra Canal,
Hugh Dickins, Baolin Wang, Andrew Morton, Loïc Molinari,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: linux-kernel, dri-devel, intel-gfx, linux-mm, kernel
Introduce the 'panfrost.transparent_hugepage' boolean module parameter
(false by default). When the parameter is set to true, a new tmpfs
mount point is created and mounted using the 'huge=within_size'
option. It's then used at GEM object creation instead of the default
'shm_mnt' mount point in order to enable Transparent Hugepage (THP)
for the object (without having to rely on a system wide parameter).
Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
---
drivers/gpu/drm/panfrost/panfrost_device.c | 4 +++
drivers/gpu/drm/panfrost/panfrost_device.h | 2 ++
drivers/gpu/drm/panfrost/panfrost_drv.c | 6 +++++
drivers/gpu/drm/panfrost/panfrost_drv.h | 11 ++++++++
drivers/gpu/drm/panfrost/panfrost_gem.c | 29 +++++++++++++++++++++-
drivers/gpu/drm/panfrost/panfrost_gem.h | 3 +++
6 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/drm/panfrost/panfrost_drv.h
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index 04bec27449cb..8f551c598a5c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -12,6 +12,7 @@
#include "panfrost_device.h"
#include "panfrost_devfreq.h"
#include "panfrost_features.h"
+#include "panfrost_gem.h"
#include "panfrost_issues.h"
#include "panfrost_gpu.h"
#include "panfrost_job.h"
@@ -266,6 +267,8 @@ int panfrost_device_init(struct panfrost_device *pfdev)
if (err)
goto out_job;
+ panfrost_gem_init(pfdev);
+
return 0;
out_job:
panfrost_job_fini(pfdev);
@@ -288,6 +291,7 @@ int panfrost_device_init(struct panfrost_device *pfdev)
void panfrost_device_fini(struct panfrost_device *pfdev)
{
+ panfrost_gem_fini(pfdev);
panfrost_perfcnt_fini(pfdev);
panfrost_job_fini(pfdev);
panfrost_mmu_fini(pfdev);
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
index 1e73efad02a8..b8f368aef9e4 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -177,6 +177,8 @@ struct panfrost_device {
spinlock_t lock;
} cycle_counter;
+ struct vfsmount *huge_mnt;
+
#ifdef CONFIG_DEBUG_FS
struct panfrost_device_debugfs debugfs;
#endif
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 22350ce8a08f..e376e70a3379 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -862,6 +862,12 @@ static const struct drm_driver panfrost_drm_driver = {
#endif
};
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+bool panfrost_transparent_hugepage;
+module_param_named(transparent_hugepage, panfrost_transparent_hugepage, bool, 0400);
+MODULE_PARM_DESC(transparent_hugepage, "Use a dedicated tmpfs mount point with Transparent Hugepage enabled (false = default)");
+#endif
+
static int panfrost_probe(struct platform_device *pdev)
{
struct panfrost_device *pfdev;
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.h b/drivers/gpu/drm/panfrost/panfrost_drv.h
new file mode 100644
index 000000000000..60454611b6a6
--- /dev/null
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0 or MIT
+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
+
+#ifndef __PANFROST_DRV_H__
+#define __PANFROST_DRV_H__
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern bool panfrost_transparent_hugepage;
+#endif
+
+#endif
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 85d6289a6eda..e560934bbf76 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
#include <linux/cleanup.h>
#include <linux/err.h>
@@ -9,9 +10,34 @@
#include <drm/panfrost_drm.h>
#include "panfrost_device.h"
+#include "panfrost_drv.h"
#include "panfrost_gem.h"
#include "panfrost_mmu.h"
+void panfrost_gem_init(struct panfrost_device *pfdev)
+{
+ struct vfsmount *huge_mnt;
+
+ if (!panfrost_transparent_hugepage)
+ return;
+
+ huge_mnt = drm_gem_shmem_huge_mnt_create("within_size");
+ if (IS_ERR(huge_mnt)) {
+ drm_warn(pfdev->ddev, "Can't use Transparent Hugepage (%ld)\n",
+ PTR_ERR(huge_mnt));
+ return;
+ }
+
+ pfdev->huge_mnt = huge_mnt;
+
+ drm_info(pfdev->ddev, "Using Transparent Hugepage\n");
+}
+
+void panfrost_gem_fini(struct panfrost_device *pfdev)
+{
+ drm_gem_shmem_huge_mnt_free(pfdev->huge_mnt);
+}
+
#ifdef CONFIG_DEBUG_FS
static void panfrost_gem_debugfs_bo_add(struct panfrost_device *pfdev,
struct panfrost_gem_object *bo)
@@ -305,6 +331,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
struct panfrost_gem_object *
panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
{
+ struct panfrost_device *pfdev = dev->dev_private;
struct drm_gem_shmem_object *shmem;
struct panfrost_gem_object *bo;
@@ -312,7 +339,7 @@ panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
if (flags & PANFROST_BO_HEAP)
size = roundup(size, SZ_2M);
- shmem = drm_gem_shmem_create(dev, size);
+ shmem = drm_gem_shmem_create_with_mnt(dev, size, pfdev->huge_mnt);
if (IS_ERR(shmem))
return ERR_CAST(shmem);
diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panfrost/panfrost_gem.h
index 8de3e76f2717..0e874d3c1363 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.h
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.h
@@ -124,6 +124,9 @@ drm_mm_node_to_panfrost_mapping(struct drm_mm_node *node)
return container_of(node, struct panfrost_gem_mapping, mmnode);
}
+void panfrost_gem_init(struct panfrost_device *pfdev);
+void panfrost_gem_fini(struct panfrost_device *pfdev);
+
struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size);
struct drm_gem_object *
--
2.47.3
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-29 20:03 ` [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop Loïc Molinari
@ 2025-09-30 10:05 ` kernel test robot
2025-09-30 10:30 ` Boris Brezillon
1 sibling, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-09-30 10:05 UTC (permalink / raw)
To: Loïc Molinari, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon,
Rob Herring, Steven Price, Liviu Dudau, Melissa Wen,
Maíra Canal, Hugh Dickins, Baolin Wang, Andrew Morton,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
dri-devel, intel-gfx, kernel
Hi Loïc,
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on linus/master v6.17 next-20250929]
[cannot apply to akpm-mm/mm-everything]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Lo-c-Molinari/drm-shmem-helper-Add-huge-page-fault-handler/20250930-040600
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20250929200316.18417-3-loic.molinari%40collabora.com
patch subject: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
config: arm-randconfig-002-20250930 (https://download.01.org/0day-ci/archive/20250930/202509301702.DL6CeU62-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250930/202509301702.DL6CeU62-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509301702.DL6CeU62-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/gpu/drm/drm_gem.c: In function 'drm_gem_get_unmapped_area':
>> drivers/gpu/drm/drm_gem.c:1280:9: error: implicit declaration of function 'mm_get_unmapped_area'; did you mean 'shmem_get_unmapped_area'? [-Werror=implicit-function-declaration]
return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
^~~~~~~~~~~~~~~~~~~~
shmem_get_unmapped_area
cc1: some warnings being treated as errors
vim +1280 drivers/gpu/drm/drm_gem.c
1238
1239 /**
1240 * drm_gem_get_unmapped_area - get memory mapping region routine for GEM objects
1241 * @filp: DRM file pointer
1242 * @uaddr: User address hint
1243 * @len: Mapping length
1244 * @pgoff: Offset (in pages)
1245 * @flags: Mapping flags
1246 *
1247 * If a driver supports GEM object mapping, before ending up in drm_gem_mmap(),
1248 * mmap calls on the DRM file descriptor will first try to find a free linear
1249 * address space large enough for a mapping. Since GEM objects are backed by
1250 * shmem buffers, this should preferably be handled by the shmem virtual memory
1251 * filesystem which can appropriately align addresses to huge page sizes when
1252 * needed.
1253 *
1254 * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
1255 * contain the fake offset we created) and call shmem_get_unmapped_area() with
1256 * the right file pointer.
1257 *
1258 * If a GEM object is not available at the given offset or if the caller is not
1259 * granted access to it, fall back to mm_get_unmapped_area().
1260 */
1261 unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
1262 unsigned long len, unsigned long pgoff,
1263 unsigned long flags)
1264 {
1265 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
1266 struct drm_gem_object *obj;
1267 unsigned long ret;
1268
1269 obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
1270 if (IS_ERR(obj))
1271 return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
1272 flags);
1273
1274 ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
1275
1276 drm_gem_object_put(obj);
1277
1278 return ret;
1279 #else
> 1280 return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
1281 #endif
1282 }
1283 EXPORT_SYMBOL(drm_gem_get_unmapped_area);
1284
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-29 20:03 ` [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop Loïc Molinari
2025-09-30 10:05 ` kernel test robot
@ 2025-09-30 10:30 ` Boris Brezillon
2025-09-30 10:45 ` Boris Brezillon
2025-09-30 16:09 ` Loïc Molinari
1 sibling, 2 replies; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 10:30 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Mon, 29 Sep 2025 22:03:10 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> mmap() calls on the drm file pointer currently always end up using
> mm_get_unmapped_area() to get a free mapping region. On builds with
> CONFIG_TRANSPARENT_HUGEPAGE enabled, this isn't ideal for GEM objects
> backed by shmem buffers on mount points setting the 'huge=' option
> because it can't correctly figure out the potentially huge address
> alignment required.
>
> This commit introduces the drm_gem_get_unmapped_area() function which
> is meant to be used as a get_unmapped_area file operation on the drm
> file pointer to lookup GEM objects based on their fake offsets and get
> a properly aligned region by calling shmem_get_unmapped_area() with
> the right file pointer. If a GEM object isn't available at the given
> offset or if the caller isn't granted access to it, the function falls
> back to mm_get_unmapped_area().
>
> This also makes drm_gem_get_unmapped_area() part of the default GEM
> file operations so that all the drm drivers can benefit from more
> efficient mappings thanks to the huge page fault handler introduced in
> previous commit 'drm/shmem-helper: Add huge page fault handler'.
>
> The shmem_get_unmapped_area() function needs to be exported so that
> it can be used from the drm subsystem.
>
> Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
> ---
> drivers/gpu/drm/drm_gem.c | 110 ++++++++++++++++++++++++++++++--------
> include/drm/drm_gem.h | 4 ++
> mm/shmem.c | 1 +
> 3 files changed, 93 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
> index cbeb76b2124f..d027db462c2d 100644
> --- a/drivers/gpu/drm/drm_gem.c
> +++ b/drivers/gpu/drm/drm_gem.c
> @@ -1187,36 +1187,27 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
> }
> EXPORT_SYMBOL(drm_gem_mmap_obj);
>
> -/**
> - * drm_gem_mmap - memory map routine for GEM objects
> - * @filp: DRM file pointer
> - * @vma: VMA for the area to be mapped
> - *
> - * If a driver supports GEM object mapping, mmap calls on the DRM file
> - * descriptor will end up here.
> - *
> - * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
> - * contain the fake offset we created when the GTT map ioctl was called on
> - * the object) and map it with a call to drm_gem_mmap_obj().
> - *
> - * If the caller is not granted access to the buffer object, the mmap will fail
> - * with EACCES. Please see the vma manager for more information.
> +/*
> + * Look up a GEM object in offset space based on the exact start address. The
> + * caller must be granted access to the object. Returns a GEM object on success
> + * or a negative error code on failure. The returned GEM object needs to be
> + * released with drm_gem_object_put().
> */
> -int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> +static struct drm_gem_object *
> +drm_gem_object_lookup_from_offset(struct file *filp, unsigned long start,
> + unsigned long pages)
> {
> struct drm_file *priv = filp->private_data;
> struct drm_device *dev = priv->minor->dev;
> struct drm_gem_object *obj = NULL;
> struct drm_vma_offset_node *node;
> - int ret;
>
> if (drm_dev_is_unplugged(dev))
> - return -ENODEV;
> + return ERR_PTR(-ENODEV);
>
> drm_vma_offset_lock_lookup(dev->vma_offset_manager);
> node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
> - vma->vm_pgoff,
> - vma_pages(vma));
> + start, pages);
> if (likely(node)) {
> obj = container_of(node, struct drm_gem_object, vma_node);
> /*
> @@ -1235,14 +1226,89 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
>
> if (!obj)
> - return -EINVAL;
> + return ERR_PTR(-EINVAL);
>
> if (!drm_vma_node_is_allowed(node, priv)) {
> drm_gem_object_put(obj);
> - return -EACCES;
> + return ERR_PTR(-EACCES);
> }
>
> - ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT,
> + return obj;
> +}
> +
> +/**
> + * drm_gem_get_unmapped_area - get memory mapping region routine for GEM objects
> + * @filp: DRM file pointer
> + * @uaddr: User address hint
> + * @len: Mapping length
> + * @pgoff: Offset (in pages)
> + * @flags: Mapping flags
> + *
> + * If a driver supports GEM object mapping, before ending up in drm_gem_mmap(),
> + * mmap calls on the DRM file descriptor will first try to find a free linear
> + * address space large enough for a mapping. Since GEM objects are backed by
> + * shmem buffers, this should preferably be handled by the shmem virtual memory
> + * filesystem which can appropriately align addresses to huge page sizes when
> + * needed.
> + *
> + * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
> + * contain the fake offset we created) and call shmem_get_unmapped_area() with
> + * the right file pointer.
> + *
> + * If a GEM object is not available at the given offset or if the caller is not
> + * granted access to it, fall back to mm_get_unmapped_area().
> + */
> +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
> + unsigned long len, unsigned long pgoff,
> + unsigned long flags)
> +{
> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> + struct drm_gem_object *obj;
> + unsigned long ret;
> +
> + obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
> + if (IS_ERR(obj))
Is this supposed to happen? If not, I'd be tempted to add a
WARN_ON_ONCE().
> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
> + flags);
> +
> + ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
> +
> + drm_gem_object_put(obj);
> +
> + return ret;
> +#else
> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
Looks like the above code covers the non-THP case too, do we really need
to specialize for !CONFIG_TRANSPARENT_HUGEPAGE here?
> +#endif
> +}
> +EXPORT_SYMBOL(drm_gem_get_unmapped_area);
> +
> +/**
> + * drm_gem_mmap - memory map routine for GEM objects
> + * @filp: DRM file pointer
> + * @vma: VMA for the area to be mapped
> + *
> + * If a driver supports GEM object mapping, mmap calls on the DRM file
> + * descriptor will end up here.
> + *
> + * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
> + * contain the fake offset we created) and map it with a call to
> + * drm_gem_mmap_obj().
> + *
> + * If the caller is not granted access to the buffer object, the mmap will fail
> + * with EACCES. Please see the vma manager for more information.
> + */
> +int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
> +{
> + struct drm_gem_object *obj;
> + int ret;
> +
> + obj = drm_gem_object_lookup_from_offset(filp, vma->vm_pgoff,
> + vma_pages(vma));
> + if (IS_ERR(obj))
> + return PTR_ERR(obj);
> +
> + ret = drm_gem_mmap_obj(obj,
> + drm_vma_node_size(&obj->vma_node) << PAGE_SHIFT,
> vma);
>
> drm_gem_object_put(obj);
> diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
> index 8d48d2af2649..7c8bd67d087c 100644
> --- a/include/drm/drm_gem.h
> +++ b/include/drm/drm_gem.h
> @@ -469,6 +469,7 @@ struct drm_gem_object {
> .poll = drm_poll,\
> .read = drm_read,\
> .llseek = noop_llseek,\
> + .get_unmapped_area = drm_gem_get_unmapped_area,\
> .mmap = drm_gem_mmap, \
> .fop_flags = FOP_UNSIGNED_OFFSET
>
> @@ -506,6 +507,9 @@ void drm_gem_vm_close(struct vm_area_struct *vma);
> int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size,
> struct vm_area_struct *vma);
> int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
> +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
> + unsigned long len, unsigned long pgoff,
> + unsigned long flags);
>
> /**
> * drm_gem_object_get - acquire a GEM buffer object reference
> diff --git a/mm/shmem.c b/mm/shmem.c
> index e2c76a30802b..b2f41b430daa 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -2915,6 +2915,7 @@ unsigned long shmem_get_unmapped_area(struct file *file,
> return addr;
> return inflated_addr;
> }
> +EXPORT_SYMBOL_GPL(shmem_get_unmapped_area);
>
> #ifdef CONFIG_NUMA
> static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *mpol)
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-29 20:03 ` [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option Loïc Molinari
@ 2025-09-30 10:34 ` Boris Brezillon
2025-09-30 16:31 ` Loïc Molinari
2025-09-30 10:36 ` kernel test robot
1 sibling, 1 reply; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 10:34 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Mon, 29 Sep 2025 22:03:14 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> Introduce the 'panthor.transparent_hugepage' boolean module parameter
> (false by default). When the parameter is set to true, a new tmpfs
> mount point is created and mounted using the 'huge=within_size'
> option. It's then used at GEM object creation instead of the default
> 'shm_mnt' mount point in order to enable Transparent Hugepage (THP)
> for the object (without having to rely on a system wide parameter).
>
> Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
> ---
> drivers/gpu/drm/panthor/panthor_device.c | 4 ++++
> drivers/gpu/drm/panthor/panthor_device.h | 3 +++
> drivers/gpu/drm/panthor/panthor_drv.c | 7 ++++++
> drivers/gpu/drm/panthor/panthor_drv.h | 11 +++++++++
> drivers/gpu/drm/panthor/panthor_gem.c | 30 +++++++++++++++++++++++-
> drivers/gpu/drm/panthor/panthor_gem.h | 3 +++
> 6 files changed, 57 insertions(+), 1 deletion(-)
> create mode 100644 drivers/gpu/drm/panthor/panthor_drv.h
>
> diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
> index 81df49880bd8..4f254b574287 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.c
> +++ b/drivers/gpu/drm/panthor/panthor_device.c
> @@ -17,6 +17,7 @@
> #include "panthor_devfreq.h"
> #include "panthor_device.h"
> #include "panthor_fw.h"
> +#include "panthor_gem.h"
> #include "panthor_gpu.h"
> #include "panthor_hw.h"
> #include "panthor_mmu.h"
> @@ -98,6 +99,7 @@ void panthor_device_unplug(struct panthor_device *ptdev)
> /* Now, try to cleanly shutdown the GPU before the device resources
> * get reclaimed.
> */
> + panthor_gem_fini(ptdev);
> panthor_sched_unplug(ptdev);
> panthor_fw_unplug(ptdev);
> panthor_mmu_unplug(ptdev);
> @@ -269,6 +271,8 @@ int panthor_device_init(struct panthor_device *ptdev)
> if (ret)
> goto err_unplug_fw;
>
> + panthor_gem_init(ptdev);
> +
> /* ~3 frames */
> pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50);
> pm_runtime_use_autosuspend(ptdev->base.dev);
> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
> index 4fc7cf2aeed5..54ca61567426 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.h
> +++ b/drivers/gpu/drm/panthor/panthor_device.h
> @@ -135,6 +135,9 @@ struct panthor_device {
> /** @devfreq: Device frequency scaling management data. */
> struct panthor_devfreq *devfreq;
>
> + /** @huge_mnt: tmpfs mount point with Transparent Hugepage enabled. */
> + struct vfsmount *huge_mnt;
Now that we have a helper to create a huge mountpoint, wouldn't it
make sense to have this field in drm_device instead of having each
driver add a huge_mnt field to their <driver>_device object.
> +
> /** @unplug: Device unplug related fields. */
> struct {
> /** @lock: Lock used to serialize unplug operations. */
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c
> index fdbe89ef7f43..a2be3b904ca2 100644
> --- a/drivers/gpu/drm/panthor/panthor_drv.c
> +++ b/drivers/gpu/drm/panthor/panthor_drv.c
> @@ -1556,6 +1556,7 @@ static const struct file_operations panthor_drm_driver_fops = {
> .read = drm_read,
> .llseek = noop_llseek,
> .mmap = panthor_mmap,
> + .get_unmapped_area = drm_gem_get_unmapped_area,
> .show_fdinfo = drm_show_fdinfo,
> .fop_flags = FOP_UNSIGNED_OFFSET,
> };
> @@ -1623,6 +1624,12 @@ static const struct drm_driver panthor_drm_driver = {
> #endif
> };
>
> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> +bool panthor_transparent_hugepage;
> +module_param_named(transparent_hugepage, panthor_transparent_hugepage, bool, 0400);
> +MODULE_PARM_DESC(transparent_hugepage, "Use a dedicated tmpfs mount point with Transparent Hugepage enabled (false = default)");
> +#endif
> +
> static int panthor_probe(struct platform_device *pdev)
> {
> struct panthor_device *ptdev;
> diff --git a/drivers/gpu/drm/panthor/panthor_drv.h b/drivers/gpu/drm/panthor/panthor_drv.h
> new file mode 100644
> index 000000000000..27fe9b6f77bd
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_drv.h
> @@ -0,0 +1,11 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* Copyright 2025 Amazon.com, Inc. or its affiliates */
> +
> +#ifndef __PANTHOR_DRV_H__
> +#define __PANTHOR_DRV_H__
> +
> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> +extern bool panthor_transparent_hugepage;
> +#endif
> +
> +#endif
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c
> index 156c7a0b62a2..16916e0b6d89 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.c
> +++ b/drivers/gpu/drm/panthor/panthor_gem.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0 or MIT
> /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
> /* Copyright 2023 Collabora ltd. */
> +/* Copyright 2025 Amazon.com, Inc. or its affiliates */
>
> #include <linux/cleanup.h>
> #include <linux/dma-buf.h>
> @@ -11,10 +12,35 @@
> #include <drm/panthor_drm.h>
>
> #include "panthor_device.h"
> +#include "panthor_drv.h"
> #include "panthor_fw.h"
> #include "panthor_gem.h"
> #include "panthor_mmu.h"
>
> +void panthor_gem_init(struct panthor_device *ptdev)
> +{
> + struct vfsmount *huge_mnt;
> +
> + if (!panthor_transparent_hugepage)
> + return;
> +
> + huge_mnt = drm_gem_shmem_huge_mnt_create("within_size");
> + if (IS_ERR(huge_mnt)) {
> + drm_warn(&ptdev->base, "Can't use Transparent Hugepage (%ld)\n",
> + PTR_ERR(huge_mnt));
> + return;
> + }
> +
> + ptdev->huge_mnt = huge_mnt;
> +
> + drm_info(&ptdev->base, "Using Transparent Hugepage\n");
> +}
> +
> +void panthor_gem_fini(struct panthor_device *ptdev)
> +{
> + drm_gem_shmem_huge_mnt_free(ptdev->huge_mnt);
> +}
> +
> #ifdef CONFIG_DEBUG_FS
> static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo)
> {
> @@ -270,10 +296,12 @@ panthor_gem_create_with_handle(struct drm_file *file,
> u64 *size, u32 flags, u32 *handle)
> {
> int ret;
> + struct panthor_device *ptdev =
> + container_of(ddev, struct panthor_device, base);
> struct drm_gem_shmem_object *shmem;
> struct panthor_gem_object *bo;
>
> - shmem = drm_gem_shmem_create(ddev, *size);
> + shmem = drm_gem_shmem_create_with_mnt(ddev, *size, ptdev->huge_mnt);
> if (IS_ERR(shmem))
> return PTR_ERR(shmem);
>
> diff --git a/drivers/gpu/drm/panthor/panthor_gem.h b/drivers/gpu/drm/panthor/panthor_gem.h
> index 80c6e24112d0..6804b3912cc2 100644
> --- a/drivers/gpu/drm/panthor/panthor_gem.h
> +++ b/drivers/gpu/drm/panthor/panthor_gem.h
> @@ -136,6 +136,9 @@ struct panthor_gem_object *to_panthor_bo(struct drm_gem_object *obj)
> return container_of(to_drm_gem_shmem_obj(obj), struct panthor_gem_object, base);
> }
>
> +void panthor_gem_init(struct panthor_device *ptdev);
> +void panthor_gem_fini(struct panthor_device *ptdev);
> +
> struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t size);
>
> int
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-29 20:03 ` [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option Loïc Molinari
2025-09-30 10:34 ` Boris Brezillon
@ 2025-09-30 10:36 ` kernel test robot
1 sibling, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-09-30 10:36 UTC (permalink / raw)
To: Loïc Molinari, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon,
Rob Herring, Steven Price, Liviu Dudau, Melissa Wen,
Maíra Canal, Hugh Dickins, Baolin Wang, Andrew Morton,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
dri-devel, intel-gfx, kernel
Hi Loïc,
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[cannot apply to akpm-mm/mm-everything linus/master v6.17 next-20250929]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Lo-c-Molinari/drm-shmem-helper-Add-huge-page-fault-handler/20250930-040600
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20250929200316.18417-7-loic.molinari%40collabora.com
patch subject: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
config: i386-buildonly-randconfig-004-20250930 (https://download.01.org/0day-ci/archive/20250930/202509301834.aoEcLO0C-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250930/202509301834.aoEcLO0C-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509301834.aoEcLO0C-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/gpu/drm/panthor/panthor_gem.c: In function 'panthor_gem_init':
>> drivers/gpu/drm/panthor/panthor_gem.c:24:14: error: 'panthor_transparent_hugepage' undeclared (first use in this function); did you mean 'has_transparent_hugepage'?
24 | if (!panthor_transparent_hugepage)
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| has_transparent_hugepage
drivers/gpu/drm/panthor/panthor_gem.c:24:14: note: each undeclared identifier is reported only once for each function it appears in
vim +24 drivers/gpu/drm/panthor/panthor_gem.c
19
20 void panthor_gem_init(struct panthor_device *ptdev)
21 {
22 struct vfsmount *huge_mnt;
23
> 24 if (!panthor_transparent_hugepage)
25 return;
26
27 huge_mnt = drm_gem_shmem_huge_mnt_create("within_size");
28 if (IS_ERR(huge_mnt)) {
29 drm_warn(&ptdev->base, "Can't use Transparent Hugepage (%ld)\n",
30 PTR_ERR(huge_mnt));
31 return;
32 }
33
34 ptdev->huge_mnt = huge_mnt;
35
36 drm_info(&ptdev->base, "Using Transparent Hugepage\n");
37 }
38
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs
2025-09-29 20:03 ` [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs Loïc Molinari
@ 2025-09-30 10:37 ` Boris Brezillon
0 siblings, 0 replies; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 10:37 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Mon, 29 Sep 2025 22:03:15 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> Log the number of pages and their sizes actually mapped/unmapped by
> the IOMMU page table driver. Since a map/unmap op is often split in
> several ops depending on the underlying scatter/gather table, add the
> start address and the total size to the debugging logs in order to
> help understand which batch an op is part of.
>
> Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
> ---
> drivers/gpu/drm/panthor/panthor_mmu.c | 19 ++++++++++++++-----
> 1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c
> index 6dec4354e378..aefbd83d1a75 100644
> --- a/drivers/gpu/drm/panthor/panthor_mmu.c
> +++ b/drivers/gpu/drm/panthor/panthor_mmu.c
> @@ -917,10 +917,9 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
> {
> struct panthor_device *ptdev = vm->ptdev;
> struct io_pgtable_ops *ops = vm->pgtbl_ops;
> + u64 start_iova = iova;
> u64 offset = 0;
>
> - drm_dbg(&ptdev->base, "unmap: as=%d, iova=%llx, len=%llx", vm->as.id, iova, size);
> -
> while (offset < size) {
> size_t unmapped_sz = 0, pgcount;
> size_t pgsize = get_pgsize(iova + offset, size - offset, &pgcount);
> @@ -935,6 +934,12 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
> panthor_vm_flush_range(vm, iova, offset + unmapped_sz);
> return -EINVAL;
> }
> +
> + drm_dbg(&ptdev->base,
> + "unmap: as=%d, iova=0x%llx, sz=%llu, va=0x%llx, pgcnt=%zu, pgsz=%zu",
> + vm->as.id, start_iova, size, iova + offset,
> + unmapped_sz / pgsize, pgsize);
> +
> offset += unmapped_sz;
> }
>
> @@ -950,6 +955,7 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot,
> struct scatterlist *sgl;
> struct io_pgtable_ops *ops = vm->pgtbl_ops;
> u64 start_iova = iova;
> + u64 start_size = size;
> int ret;
>
> if (!size)
> @@ -969,15 +975,18 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot,
> len = min_t(size_t, len, size);
> size -= len;
>
> - drm_dbg(&ptdev->base, "map: as=%d, iova=%llx, paddr=%pad, len=%zx",
> - vm->as.id, iova, &paddr, len);
> -
> while (len) {
> size_t pgcount, mapped = 0;
> size_t pgsize = get_pgsize(iova | paddr, len, &pgcount);
>
> ret = ops->map_pages(ops, iova, paddr, pgsize, pgcount, prot,
> GFP_KERNEL, &mapped);
> +
> + drm_dbg(&ptdev->base,
> + "map: as=%d, iova=0x%llx, sz=%llu, va=0x%llx, pa=%pad, pgcnt=%zu, pgsz=%zu",
> + vm->as.id, start_iova, start_size, iova, &paddr,
> + mapped / pgsize, pgsize);
> +
> iova += mapped;
> paddr += mapped;
> len -= mapped;
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-30 10:30 ` Boris Brezillon
@ 2025-09-30 10:45 ` Boris Brezillon
2025-09-30 16:09 ` Loïc Molinari
1 sibling, 0 replies; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 10:45 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Tue, 30 Sep 2025 12:30:03 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:
> > +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
> > + unsigned long len, unsigned long pgoff,
> > + unsigned long flags)
> > +{
> > +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> > + struct drm_gem_object *obj;
> > + unsigned long ret;
> > +
> > + obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
> > + if (IS_ERR(obj))
>
> Is this supposed to happen? If not, I'd be tempted to add a
> WARN_ON_ONCE().
Taking that back. I think you need it for non-GEM backed mappings, like
userland IOMEM mappings.
>
> > + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
> > + flags);
> > +
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers
2025-09-29 20:03 ` [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers Loïc Molinari
@ 2025-09-30 10:57 ` Boris Brezillon
0 siblings, 0 replies; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 10:57 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Mon, 29 Sep 2025 22:03:11 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> Add the drm_gem_shmem_helper_huge_mnt_create() and
> drm_gem_shmem_helper_huge_mnt_free() helpers to avoid code duplication
> in the i915 and v3d drivers (and soon panfrost/panthor).
>
> Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
> ---
> drivers/gpu/drm/drm_gem_shmem_helper.c | 56 ++++++++++++++++++++++++++
> include/drm/drm_gem_shmem_helper.h | 14 +++++++
> 2 files changed, 70 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
> index 22c4b09e10a3..808721b8be3e 100644
> --- a/drivers/gpu/drm/drm_gem_shmem_helper.c
> +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
> @@ -5,7 +5,9 @@
>
> #include <linux/dma-buf.h>
> #include <linux/export.h>
> +#include <linux/fs_context.h>
> #include <linux/module.h>
> +#include <linux/mount.h>
> #include <linux/mutex.h>
> #include <linux/shmem_fs.h>
> #include <linux/slab.h>
> @@ -36,6 +38,60 @@ MODULE_IMPORT_NS("DMA_BUF");
> * drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
> */
>
> +static int drm_gem_shmem_add_fc_param(struct fs_context *fc, const char *key,
> + const char *value)
> +{
> + return vfs_parse_fs_string(fc, key, value, strlen(value));
> +}
> +
> +/**
> + * drm_gem_shmem_huge_mnt_create - Create a huge tmpfs mountpoint
> + * @value: huge tmpfs mount option value
> + *
> + * This function creates and mounts an internal huge tmpfs mountpoint for use
> + * with the drm_gem_shmem_create_with_mnt() function.
> + *
> + * The most common option value is "within_size" which only allocates huge pages
> + * if the page will be fully within the GEM object size. "always", "advise" and
> + * "never" are supported too but the latter would just create a mountpoint
> + * similar to default "shm_mnt" one. See shmemfs and Transparent Hugepage for
> + * more information.
> + *
> + * Returns:
> + * A struct vfsmount * on success or an ERR_PTR()-encoded negative error code on
> + * failure.
> + */
> +struct vfsmount *drm_gem_shmem_huge_mnt_create(const char *value)
Given drm_gem_object_init_with_mnt() lives in drm_gem.c and doesn't
have the _shmem_ prefix, I'd be tempted to move this helper to
drm_gem.c and rename it drm_gem_huge_mnt_create(). Actually, as I said
in the panthor patch, I believe this could also be passed a drm_device
and have the resulting vfsmount stored in drm_device::huge_mnt. This
way we could get rid of drm_gem_shmem_create_with_mnt() altogether.
> +{
> + struct file_system_type *type;
> + struct fs_context *fc;
> + struct vfsmount *mnt;
> + int ret;
> +
> + if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
> + return ERR_PTR(-EOPNOTSUPP);
> +
> + type = get_fs_type("tmpfs");
> + if (!type)
> + return ERR_PTR(-EOPNOTSUPP);
> +
> + fc = fs_context_for_mount(type, SB_KERNMOUNT);
> + if (IS_ERR(fc))
> + return ERR_CAST(fc);
> + ret = drm_gem_shmem_add_fc_param(fc, "source", "tmpfs");
> + if (ret)
> + return ERR_PTR(-ENOPARAM);
> + ret = drm_gem_shmem_add_fc_param(fc, "huge", value);
> + if (ret)
> + return ERR_PTR(-ENOPARAM);
> +
> + mnt = fc_mount_longterm(fc);
> + put_fs_context(fc);
> +
> + return mnt;
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_shmem_huge_mnt_create);
> +
> static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
> .free = drm_gem_shmem_object_free,
> .print_info = drm_gem_shmem_object_print_info,
> diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
> index 589f7bfe7506..5e153fb63f38 100644
> --- a/include/drm/drm_gem_shmem_helper.h
> +++ b/include/drm/drm_gem_shmem_helper.h
> @@ -107,6 +107,20 @@ struct drm_gem_shmem_object {
> #define to_drm_gem_shmem_obj(obj) \
> container_of(obj, struct drm_gem_shmem_object, base)
>
> +struct vfsmount *drm_gem_shmem_huge_mnt_create(const char *value);
> +
> +/**
> + * drm_gem_shmem_huge_mnt_free - Release a huge tmpfs mountpoint.
> + * @mnt: struct vfsmount * to release
> + *
> + * This function unmounts and releases an internal huge tmpfs mountpoint. If
> + * @mnt is NULL, no operation is performed.
> + */
> +static inline void drm_gem_shmem_huge_mnt_free(struct vfsmount *mnt)
> +{
> + kern_unmount(mnt);
> +}
> +
> int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size);
> struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
> struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/8] drm/i915: Use huge tmpfs mount point helpers
2025-09-29 20:03 ` [PATCH 4/8] drm/i915: Use " Loïc Molinari
@ 2025-09-30 11:06 ` kernel test robot
0 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2025-09-30 11:06 UTC (permalink / raw)
To: Loïc Molinari, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Jani Nikula,
Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin, Boris Brezillon,
Rob Herring, Steven Price, Liviu Dudau, Melissa Wen,
Maíra Canal, Hugh Dickins, Baolin Wang, Andrew Morton,
Al Viro, Mikołaj Wasiak, Christian Brauner, Nitin Gote,
Andi Shyti
Cc: oe-kbuild-all, Linux Memory Management List, linux-kernel,
dri-devel, intel-gfx, kernel
Hi Loïc,
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[cannot apply to akpm-mm/mm-everything linus/master v6.17 next-20250929]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Lo-c-Molinari/drm-shmem-helper-Add-huge-page-fault-handler/20250930-040600
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20250929200316.18417-5-loic.molinari%40collabora.com
patch subject: [PATCH 4/8] drm/i915: Use huge tmpfs mount point helpers
config: i386-randconfig-013-20250930 (https://download.01.org/0day-ci/archive/20250930/202509301837.pQ2TiJkx-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250930/202509301837.pQ2TiJkx-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509301837.pQ2TiJkx-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/gpu/drm/i915/gem/i915_gemfs.c: In function 'i915_gemfs_init':
>> drivers/gpu/drm/i915/gem/i915_gemfs.c:29:17: error: implicit declaration of function 'drm_gem_shmem_huge_mnt_create' [-Wimplicit-function-declaration]
29 | gemfs = drm_gem_shmem_huge_mnt_create("within_size");
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/gpu/drm/i915/gem/i915_gemfs.c:29:15: error: assignment to 'struct vfsmount *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
29 | gemfs = drm_gem_shmem_huge_mnt_create("within_size");
| ^
drivers/gpu/drm/i915/gem/i915_gemfs.c: In function 'i915_gemfs_fini':
>> drivers/gpu/drm/i915/gem/i915_gemfs.c:46:9: error: implicit declaration of function 'drm_gem_shmem_huge_mnt_free' [-Wimplicit-function-declaration]
46 | drm_gem_shmem_huge_mnt_free(i915->mm.gemfs);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
vim +/drm_gem_shmem_huge_mnt_create +29 drivers/gpu/drm/i915/gem/i915_gemfs.c
9
10 void i915_gemfs_init(struct drm_i915_private *i915)
11 {
12 struct vfsmount *gemfs;
13
14 /*
15 * By creating our own shmemfs mountpoint, we can pass in
16 * mount flags that better match our usecase.
17 *
18 * One example, although it is probably better with a per-file
19 * control, is selecting huge page allocations ("huge=within_size").
20 * However, we only do so on platforms which benefit from it, or to
21 * offset the overhead of iommu lookups, where with latter it is a net
22 * win even on platforms which would otherwise see some performance
23 * regressions such a slow reads issue on Broadwell and Skylake.
24 */
25
26 if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915))
27 return;
28
> 29 gemfs = drm_gem_shmem_huge_mnt_create("within_size");
30 if (IS_ERR(gemfs))
31 goto err;
32
33 i915->mm.gemfs = gemfs;
34 drm_info(&i915->drm, "Using Transparent Hugepages\n");
35 return;
36
37 err:
38 drm_notice(&i915->drm,
39 "Transparent Hugepage support is recommended for optimal performance%s\n",
40 GRAPHICS_VER(i915) >= 11 ? " on this platform!" :
41 " when IOMMU is enabled!");
42 }
43
44 void i915_gemfs_fini(struct drm_i915_private *i915)
45 {
> 46 drm_gem_shmem_huge_mnt_free(i915->mm.gemfs);
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-30 10:30 ` Boris Brezillon
2025-09-30 10:45 ` Boris Brezillon
@ 2025-09-30 16:09 ` Loïc Molinari
2025-09-30 16:29 ` Boris Brezillon
1 sibling, 1 reply; 23+ messages in thread
From: Loïc Molinari @ 2025-09-30 16:09 UTC (permalink / raw)
To: Boris Brezillon
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On 30/09/2025 12:30, Boris Brezillon wrote:
> On Mon, 29 Sep 2025 22:03:10 +0200
>
> Loïc Molinari <loic.molinari@collabora.com> wrote:
>> +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
>> + unsigned long len, unsigned long pgoff,
>> + unsigned long flags)
>> +{
>> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> + struct drm_gem_object *obj;
>> + unsigned long ret;
>> +
>> + obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
>> + if (IS_ERR(obj))
>> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
>> + flags);
>> +
>> + ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
>> +
>> + drm_gem_object_put(obj);
>> +
>> + return ret;
>> +#else
>> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
>
> Looks like the above code covers the non-THP case too, do we really need
> to specialize for !CONFIG_TRANSPARENT_HUGEPAGE here?
It does cover the !CONFIG_TRANSPARENT_HUGEPAGE case
(shmem_get_unmapped_area() would just call and return the
mm_get_unmapped_area() address) but the idea here is to avoid the GEM
object lookup cost by calling mm_get_unmapped_area() directly.
>> +#endif
>> +}
>> +EXPORT_SYMBOL(drm_gem_get_unmapped_area);
Loïc
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-30 16:09 ` Loïc Molinari
@ 2025-09-30 16:29 ` Boris Brezillon
2025-09-30 16:42 ` Loïc Molinari
0 siblings, 1 reply; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 16:29 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Tue, 30 Sep 2025 18:09:37 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> On 30/09/2025 12:30, Boris Brezillon wrote:
> > On Mon, 29 Sep 2025 22:03:10 +0200
> >
> > Loïc Molinari <loic.molinari@collabora.com> wrote:
> >> +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
> >> + unsigned long len, unsigned long pgoff,
> >> + unsigned long flags)
> >> +{
> >> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
> >> + struct drm_gem_object *obj;
> >> + unsigned long ret;
> >> +
> >> + obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
> >> + if (IS_ERR(obj))
> >> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
> >> + flags);
> >> +
> >> + ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
> >> +
> >> + drm_gem_object_put(obj);
> >> +
> >> + return ret;
> >> +#else
> >> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
> >
> > Looks like the above code covers the non-THP case too, do we really need
> > to specialize for !CONFIG_TRANSPARENT_HUGEPAGE here?
>
> It does cover the !CONFIG_TRANSPARENT_HUGEPAGE case
> (shmem_get_unmapped_area() would just call and return the
> mm_get_unmapped_area() address) but the idea here is to avoid the GEM
> object lookup cost by calling mm_get_unmapped_area() directly.
I'd expect the extra GEM lookup to be negligible compared to the overall
mmap() operation to be honest, but I guess if we really want to avoid
the overhead, we could still write it without this ifdef.
if (!IS_ENABLED(TRANSPARENT_HUGEPAGE))
return mm_get_unmapped_area(current->mm, filp, uaddr,
len, 0, flags);
...
My main concern is that shmem_get_unmapped_area() evolves with more
!TRANSPARENT_HUGEPAGE cases, and by calling mm_get_unmapped_area()
directly, we miss the opportunity to get optimizations for these cases,
just like we missed them by not forwarding the ->get_unmapped_area()
requests to the shmem layer so far.
>
> >> +#endif
> >> +}
> >> +EXPORT_SYMBOL(drm_gem_get_unmapped_area);
>
> Loïc
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-30 10:34 ` Boris Brezillon
@ 2025-09-30 16:31 ` Loïc Molinari
2025-09-30 16:52 ` Boris Brezillon
0 siblings, 1 reply; 23+ messages in thread
From: Loïc Molinari @ 2025-09-30 16:31 UTC (permalink / raw)
To: Boris Brezillon
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On 30/09/2025 12:34, Boris Brezillon wrote:
> On Mon, 29 Sep 2025 22:03:14 +0200
> Loïc Molinari <loic.molinari@collabora.com> wrote:
>
>> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
>> index 4fc7cf2aeed5..54ca61567426 100644
>> --- a/drivers/gpu/drm/panthor/panthor_device.h
>> +++ b/drivers/gpu/drm/panthor/panthor_device.h
>> @@ -135,6 +135,9 @@ struct panthor_device {
>> /** @devfreq: Device frequency scaling management data. */
>> struct panthor_devfreq *devfreq;
>>
>> + /** @huge_mnt: tmpfs mount point with Transparent Hugepage enabled. */
>> + struct vfsmount *huge_mnt;
>
> Now that we have a helper to create a huge mountpoint, wouldn't it
> make sense to have this field in drm_device instead of having each
> driver add a huge_mnt field to their <driver>_device object.
Not sure this should be enforced for all DRM drivers since most of them
don't create separate huge mountpoints (only 4 for now including this
patchset) and I guess some maintainers might prefer to depend on the
sysfs interace to enable huge pages.
>> +
>> /** @unplug: Device unplug related fields. */
>> struct {
>> /** @lock: Lock used to serialize unplug operations. */
>
Loïc
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop
2025-09-30 16:29 ` Boris Brezillon
@ 2025-09-30 16:42 ` Loïc Molinari
0 siblings, 0 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-09-30 16:42 UTC (permalink / raw)
To: Boris Brezillon
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On 30/09/2025 18:29, Boris Brezillon wrote:
> On Tue, 30 Sep 2025 18:09:37 +0200
> Loïc Molinari <loic.molinari@collabora.com> wrote:
>
>> On 30/09/2025 12:30, Boris Brezillon wrote:
>>> On Mon, 29 Sep 2025 22:03:10 +0200
>>>
>>> Loïc Molinari <loic.molinari@collabora.com> wrote:
>>>> +unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
>>>> + unsigned long len, unsigned long pgoff,
>>>> + unsigned long flags)
>>>> +{
>>>> +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>>> + struct drm_gem_object *obj;
>>>> + unsigned long ret;
>>>> +
>>>> + obj = drm_gem_object_lookup_from_offset(filp, pgoff, len >> PAGE_SHIFT);
>>>> + if (IS_ERR(obj))
>>>> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0,
>>>> + flags);
>>>> +
>>>> + ret = shmem_get_unmapped_area(obj->filp, uaddr, len, 0, flags);
>>>> +
>>>> + drm_gem_object_put(obj);
>>>> +
>>>> + return ret;
>>>> +#else
>>>> + return mm_get_unmapped_area(current->mm, filp, uaddr, len, 0, flags);
>>>
>>> Looks like the above code covers the non-THP case too, do we really need
>>> to specialize for !CONFIG_TRANSPARENT_HUGEPAGE here?
>>
>> It does cover the !CONFIG_TRANSPARENT_HUGEPAGE case
>> (shmem_get_unmapped_area() would just call and return the
>> mm_get_unmapped_area() address) but the idea here is to avoid the GEM
>> object lookup cost by calling mm_get_unmapped_area() directly.
>
> I'd expect the extra GEM lookup to be negligible compared to the overall
> mmap() operation to be honest, but I guess if we really want to avoid
> the overhead, we could still write it without this ifdef.
>
> if (!IS_ENABLED(TRANSPARENT_HUGEPAGE))
> return mm_get_unmapped_area(current->mm, filp, uaddr,
> len, 0, flags);
>
> ...
>
> My main concern is that shmem_get_unmapped_area() evolves with more
> !TRANSPARENT_HUGEPAGE cases, and by calling mm_get_unmapped_area()
> directly, we miss the opportunity to get optimizations for these cases,
> just like we missed them by not forwarding the ->get_unmapped_area()
> requests to the shmem layer so far.
Yes, sounds like a very good point. I'll remove the ifdef and forward to
the shmem layer unconditionally.
>>
>>>> +#endif
>>>> +}
>>>> +EXPORT_SYMBOL(drm_gem_get_unmapped_area);
>>
>> Loïc
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-30 16:31 ` Loïc Molinari
@ 2025-09-30 16:52 ` Boris Brezillon
2025-10-04 9:39 ` Loïc Molinari
0 siblings, 1 reply; 23+ messages in thread
From: Boris Brezillon @ 2025-09-30 16:52 UTC (permalink / raw)
To: Loïc Molinari
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On Tue, 30 Sep 2025 18:31:11 +0200
Loïc Molinari <loic.molinari@collabora.com> wrote:
> On 30/09/2025 12:34, Boris Brezillon wrote:
> > On Mon, 29 Sep 2025 22:03:14 +0200
> > Loïc Molinari <loic.molinari@collabora.com> wrote:
> >
> >> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
> >> index 4fc7cf2aeed5..54ca61567426 100644
> >> --- a/drivers/gpu/drm/panthor/panthor_device.h
> >> +++ b/drivers/gpu/drm/panthor/panthor_device.h
> >> @@ -135,6 +135,9 @@ struct panthor_device {
> >> /** @devfreq: Device frequency scaling management data. */
> >> struct panthor_devfreq *devfreq;
> >>
> >> + /** @huge_mnt: tmpfs mount point with Transparent Hugepage enabled. */
> >> + struct vfsmount *huge_mnt;
> >
> > Now that we have a helper to create a huge mountpoint, wouldn't it
> > make sense to have this field in drm_device instead of having each
> > driver add a huge_mnt field to their <driver>_device object.
>
> Not sure this should be enforced for all DRM drivers since most of them
> don't create separate huge mountpoints (only 4 for now including this
> patchset) and I guess some maintainers might prefer to depend on the
> sysfs interace to enable huge pages.
I'm not saying we should create the huge mountpoint by default, but if
this is a generic helper, it makes sense to also manage this mountpoint
internally. In the end, it'd be a small price to pay for drivers that
don't need it (the size of a pointer in the drm_device object), and
with this in place, driver wouldn't even have to call
drm_gem_shmem_huge_mnt_free() manually (can be automated with a
drmm_add_action_or_reset() calling kern_unmount() inside
drm_gem_shmem_huge_mnt_create()).
>
> >> +
> >> /** @unplug: Device unplug related fields. */
> >> struct {
> >> /** @lock: Lock used to serialize unplug operations. */
> >
>
> Loïc
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option
2025-09-30 16:52 ` Boris Brezillon
@ 2025-10-04 9:39 ` Loïc Molinari
0 siblings, 0 replies; 23+ messages in thread
From: Loïc Molinari @ 2025-10-04 9:39 UTC (permalink / raw)
To: Boris Brezillon
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
David Airlie, Simona Vetter, Jani Nikula, Joonas Lahtinen,
Rodrigo Vivi, Tvrtko Ursulin, Rob Herring, Steven Price,
Liviu Dudau, Melissa Wen, Maíra Canal, Hugh Dickins,
Baolin Wang, Andrew Morton, Al Viro, Mikołaj Wasiak,
Christian Brauner, Nitin Gote, Andi Shyti, linux-kernel,
dri-devel, intel-gfx, linux-mm, kernel
On 30/09/2025 18:52, Boris Brezillon wrote:
> On Tue, 30 Sep 2025 18:31:11 +0200
> Loïc Molinari <loic.molinari@collabora.com> wrote:
>
>> On 30/09/2025 12:34, Boris Brezillon wrote:
>>> On Mon, 29 Sep 2025 22:03:14 +0200
>>> Loïc Molinari <loic.molinari@collabora.com> wrote:
>>>
>>>> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
>>>> index 4fc7cf2aeed5..54ca61567426 100644
>>>> --- a/drivers/gpu/drm/panthor/panthor_device.h
>>>> +++ b/drivers/gpu/drm/panthor/panthor_device.h
>>>> @@ -135,6 +135,9 @@ struct panthor_device {
>>>> /** @devfreq: Device frequency scaling management data. */
>>>> struct panthor_devfreq *devfreq;
>>>>
>>>> + /** @huge_mnt: tmpfs mount point with Transparent Hugepage enabled. */
>>>> + struct vfsmount *huge_mnt;
>>>
>>> Now that we have a helper to create a huge mountpoint, wouldn't it
>>> make sense to have this field in drm_device instead of having each
>>> driver add a huge_mnt field to their <driver>_device object.
>>
>> Not sure this should be enforced for all DRM drivers since most of them
>> don't create separate huge mountpoints (only 4 for now including this
>> patchset) and I guess some maintainers might prefer to depend on the
>> sysfs interace to enable huge pages.
>
> I'm not saying we should create the huge mountpoint by default, but if
> this is a generic helper, it makes sense to also manage this mountpoint
> internally. In the end, it'd be a small price to pay for drivers that
> don't need it (the size of a pointer in the drm_device object), and
> with this in place, driver wouldn't even have to call
> drm_gem_shmem_huge_mnt_free() manually (can be automated with a
> drmm_add_action_or_reset() calling kern_unmount() inside
> drm_gem_shmem_huge_mnt_create()).
Ok. I've just sent a v3 of the series with the huge vfsmount stored in
the drm_device struct. This also allowed to get rid of some of the
*_with_mnt helpers.
>
>>
>>>> +
>>>> /** @unplug: Device unplug related fields. */
>>>> struct {
>>>> /** @lock: Lock used to serialize unplug operations. */
>>>
>>
>> Loïc
>
Loïc
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2025-10-04 9:39 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-29 20:03 [PATCH 0/8] drm: Optimize page tables overhead with THP Loïc Molinari
2025-09-29 20:03 ` [PATCH 1/8] drm/shmem-helper: Add huge page fault handler Loïc Molinari
2025-09-29 20:03 ` [PATCH 2/8] drm/gem: Introduce drm_gem_get_unmapped_area() fop Loïc Molinari
2025-09-30 10:05 ` kernel test robot
2025-09-30 10:30 ` Boris Brezillon
2025-09-30 10:45 ` Boris Brezillon
2025-09-30 16:09 ` Loïc Molinari
2025-09-30 16:29 ` Boris Brezillon
2025-09-30 16:42 ` Loïc Molinari
2025-09-29 20:03 ` [PATCH 3/8] drm/shmem-helper: Add huge tmpfs mount point helpers Loïc Molinari
2025-09-30 10:57 ` Boris Brezillon
2025-09-29 20:03 ` [PATCH 4/8] drm/i915: Use " Loïc Molinari
2025-09-30 11:06 ` kernel test robot
2025-09-29 20:03 ` [PATCH 5/8] drm/v3d: " Loïc Molinari
2025-09-29 20:03 ` [PATCH 6/8] drm/panthor: Introduce huge tmpfs mount point option Loïc Molinari
2025-09-30 10:34 ` Boris Brezillon
2025-09-30 16:31 ` Loïc Molinari
2025-09-30 16:52 ` Boris Brezillon
2025-10-04 9:39 ` Loïc Molinari
2025-09-30 10:36 ` kernel test robot
2025-09-29 20:03 ` [PATCH 7/8] drm/panthor: Improve IOMMU map/unmap debugging logs Loïc Molinari
2025-09-30 10:37 ` Boris Brezillon
2025-09-29 20:03 ` [PATCH 8/8] drm/panfrost: Introduce huge tmpfs mount point option Loïc Molinari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox