Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/gem: Add huge tmpfs mountpoint helpers

Add the drm_gem_huge_mnt_create() and drm_gem_get_huge_mnt() helpers
to avoid code duplication in the i915, V3D, Panfrost and Panthor
drivers. The former creates and mounts a dedicated huge tmpfs
mountpoint, for the lifetime of a DRM device, used at GEM object
initialization. The latter retrieves the dedicated huge tmpfs
mountpoint used by a DRM device.

The next commits will port drivers to these helpers.

v3:
- store huge tmpfs mountpoint in drm_device

v4:
- return 0 in builds with CONFIG_TRANSPARENT_HUGEPAGE=n
- return 0 when huge_mnt already exists
- use new vfs_parse_fs_string() helper

v5:
- remove warning on !dev->huge_mnt and reset to NULL on free
- inline drm_gem_huge_mnt_create() to remove func from text and avoid
calls in builds with CONFIG_TRANSPARENT_HUGEPAGE=n
- compile out drm_device's huge_mnt field in builds with
CONFIG_TRANSPARENT_HUGEPAGE=n
- add drm_gem_has_huge_mnt() helper

v6:
- move huge_mnt doc into ifdef'd section
- either inline or export drm_gem_huge_mnt_create()

v7:
- include <drm/drm_device.h> in drm_gem.h

v9:
- replace drm_gem_has_huge_mnt() by drm_gem_get_huge_mnt()

v11:
- doc fixes
- add Boris and Maíra R-bs

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Link: https://patch.msgid.link/20251205182231.194072-5-loic.molinari@collabora.com
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

authored by

Loïc Molinari and committed by
Boris Brezillon
6e0b1b82 99bda20d

+105
+57
drivers/gpu/drm/drm_gem.c
··· 29 29 #include <linux/export.h> 30 30 #include <linux/file.h> 31 31 #include <linux/fs.h> 32 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 33 + #include <linux/fs_context.h> 34 + #endif 32 35 #include <linux/iosys-map.h> 33 36 #include <linux/mem_encrypt.h> 34 37 #include <linux/mm.h> ··· 84 81 * that we can transition to fds if the required kernel infrastructure shows 85 82 * up at a later date, and as our interface with shmfs for memory allocation. 86 83 */ 84 + 85 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 86 + static void drm_gem_huge_mnt_free(struct drm_device *dev, void *data) 87 + { 88 + kern_unmount(dev->huge_mnt); 89 + } 90 + 91 + /** 92 + * drm_gem_huge_mnt_create - Create, mount and use a huge tmpfs mountpoint 93 + * @dev: DRM device that will use the huge tmpfs mountpoint 94 + * @value: huge tmpfs mount option value 95 + * 96 + * This function creates and mounts a dedicated huge tmpfs mountpoint for the 97 + * lifetime of the DRM device @dev which is used at GEM object initialization 98 + * with drm_gem_object_init(). 99 + * 100 + * The most common option for @value is "within_size" which only allocates huge 101 + * pages if the page will be fully within the GEM object size. "always", 102 + * "advise" and "never" are supported too but the latter would just create a 103 + * mountpoint similar to the default one (`shm_mnt`). See shmemfs and 104 + * Transparent Hugepage for more information. 105 + * 106 + * Returns: 107 + * 0 on success or a negative error code on failure. 108 + */ 109 + int drm_gem_huge_mnt_create(struct drm_device *dev, const char *value) 110 + { 111 + struct file_system_type *type; 112 + struct fs_context *fc; 113 + int ret; 114 + 115 + if (unlikely(drm_gem_get_huge_mnt(dev))) 116 + return 0; 117 + 118 + type = get_fs_type("tmpfs"); 119 + if (unlikely(!type)) 120 + return -EOPNOTSUPP; 121 + fc = fs_context_for_mount(type, SB_KERNMOUNT); 122 + if (IS_ERR(fc)) 123 + return PTR_ERR(fc); 124 + ret = vfs_parse_fs_string(fc, "source", "tmpfs"); 125 + if (unlikely(ret)) 126 + return -ENOPARAM; 127 + ret = vfs_parse_fs_string(fc, "huge", value); 128 + if (unlikely(ret)) 129 + return -ENOPARAM; 130 + 131 + dev->huge_mnt = fc_mount_longterm(fc); 132 + put_fs_context(fc); 133 + 134 + return drmm_add_action_or_reset(dev, drm_gem_huge_mnt_free, NULL); 135 + } 136 + EXPORT_SYMBOL_GPL(drm_gem_huge_mnt_create); 137 + #endif 87 138 88 139 static void 89 140 drm_gem_init_release(struct drm_device *dev, void *ptr)
+15
include/drm/drm_device.h
··· 3 3 4 4 #include <linux/list.h> 5 5 #include <linux/kref.h> 6 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 7 + #include <linux/mount.h> 8 + #endif 6 9 #include <linux/mutex.h> 7 10 #include <linux/idr.h> 8 11 #include <linux/sched.h> ··· 170 167 * Protected by &master_mutex 171 168 */ 172 169 struct drm_master *master; 170 + 171 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 172 + /** 173 + * @huge_mnt: 174 + * 175 + * Huge tmpfs mountpoint used at GEM object initialization 176 + * drm_gem_object_init(). Drivers can call drm_gem_huge_mnt_create() to 177 + * create, mount and use it. The default tmpfs mountpoint (`shm_mnt`) is 178 + * used if NULL. 179 + */ 180 + struct vfsmount *huge_mnt; 181 + #endif 173 182 174 183 /** 175 184 * @driver_features: per-device driver features
+33
include/drm/drm_gem.h
··· 40 40 #include <linux/list.h> 41 41 #include <linux/mutex.h> 42 42 43 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 44 + #include <drm/drm_device.h> 45 + #endif 43 46 #include <drm/drm_vma_manager.h> 44 47 45 48 struct iosys_map; ··· 494 491 .owner = THIS_MODULE,\ 495 492 DRM_GEM_FOPS,\ 496 493 } 494 + 495 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 496 + int drm_gem_huge_mnt_create(struct drm_device *dev, const char *value); 497 + #else 498 + static inline int drm_gem_huge_mnt_create(struct drm_device *dev, 499 + const char *value) 500 + { 501 + return 0; 502 + } 503 + #endif 504 + 505 + /** 506 + * drm_gem_get_huge_mnt - Get the huge tmpfs mountpoint used by a DRM device 507 + * @dev: DRM device 508 + 509 + * This function gets the huge tmpfs mountpoint used by DRM device @dev. A huge 510 + * tmpfs mountpoint is used instead of `shm_mnt` after a successful call to 511 + * drm_gem_huge_mnt_create() when CONFIG_TRANSPARENT_HUGEPAGE is enabled. 512 + 513 + * Returns: 514 + * The huge tmpfs mountpoint in use, NULL otherwise. 515 + */ 516 + static inline struct vfsmount *drm_gem_get_huge_mnt(struct drm_device *dev) 517 + { 518 + #ifdef CONFIG_TRANSPARENT_HUGEPAGE 519 + return dev->huge_mnt; 520 + #else 521 + return NULL; 522 + #endif 523 + } 497 524 498 525 void drm_gem_object_release(struct drm_gem_object *obj); 499 526 void drm_gem_object_free(struct kref *kref);