Commit a8a9a590 authored by Loïc Molinari's avatar Loïc Molinari Committed by Boris Brezillon
Browse files

drm/i915: Use huge tmpfs mountpoint helpers



Make use of the new drm_gem_huge_mnt_create() and
drm_gem_get_huge_mnt() helpers to avoid code duplication. Now that
it's just a few lines long, the single function in i915_gemfs.c is
moved into i915_gem_shmem.c.

v3:
- use huge tmpfs mountpoint in drm_device
- move i915_gemfs.c into i915_gem_shmem.c

v4:
- clean up mountpoint creation error handling

v5:
- use drm_gem_has_huge_mnt() helper

v7:
- include <drm/drm_print.h> in i915_gem_shmem.c

v8:
- keep logging notice message with CONFIG_TRANSPARENT_HUGEPAGE=n
- don't access huge_mnt field with CONFIG_TRANSPARENT_HUGEPAGE=n

v9:
- replace drm_gem_has_huge_mnt() by drm_gem_get_huge_mnt()
- remove useless ternary op test in selftests/huge_pages.c

v12:
- fix layering violation in selftests (Tvrtko)
- fix incorrect filename in commit message

v13:
- add Tvrtko A-b

Signed-off-by: default avatarLoïc Molinari <loic.molinari@collabora.com>
Acked-by: default avatarTvrtko Ursulin <tursulin@ursulin.net>
Link: https://patch.msgid.link/20251205182231.194072-6-loic.molinari@collabora.com


Signed-off-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
parent 6e0b1b82
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -169,8 +169,7 @@ gem-y += \
	gem/i915_gem_ttm_move.o \
	gem/i915_gem_ttm_pm.o \
	gem/i915_gem_userptr.o \
	gem/i915_gem_wait.o \
	gem/i915_gemfs.o
	gem/i915_gem_wait.o
i915-y += \
	$(gem-y) \
	i915_active.o \
+5 −4
Original line number Diff line number Diff line
@@ -348,12 +348,13 @@ struct drm_i915_gem_object {
 */
#define I915_BO_ALLOC_GPU_ONLY	  BIT(6)
#define I915_BO_ALLOC_CCS_AUX	  BIT(7)
#define I915_BO_ALLOC_NOTHP	  BIT(8)
/*
 * Object is allowed to retain its initial data and will not be cleared on first
 * access if used along with I915_BO_ALLOC_USER. This is mainly to keep
 * preallocated framebuffer data intact while transitioning it to i915drmfb.
 */
#define I915_BO_PREALLOC	  BIT(8)
#define I915_BO_PREALLOC	  BIT(9)
#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
			     I915_BO_ALLOC_VOLATILE | \
			     I915_BO_ALLOC_CPU_CLEAR | \
@@ -363,9 +364,9 @@ struct drm_i915_gem_object {
			     I915_BO_ALLOC_GPU_ONLY | \
			     I915_BO_ALLOC_CCS_AUX | \
			     I915_BO_PREALLOC)
#define I915_BO_READONLY          BIT(9)
#define I915_TILING_QUIRK_BIT     10 /* unknown swizzling; do not release! */
#define I915_BO_PROTECTED         BIT(11)
#define I915_BO_READONLY          BIT(10)
#define I915_TILING_QUIRK_BIT     11 /* unknown swizzling; do not release! */
#define I915_BO_PROTECTED         BIT(12)
	/**
	 * @mem_flags - Mutable placement-related flags
	 *
+41 −17
Original line number Diff line number Diff line
@@ -9,14 +9,16 @@
#include <linux/uio.h>

#include <drm/drm_cache.h>
#include <drm/drm_gem.h>
#include <drm/drm_print.h>

#include "gem/i915_gem_region.h"
#include "i915_drv.h"
#include "i915_gem_object.h"
#include "i915_gem_tiling.h"
#include "i915_gemfs.h"
#include "i915_scatterlist.h"
#include "i915_trace.h"
#include "i915_utils.h"

/*
 * Move folios to appropriate lru and release the batch, decrementing the
@@ -494,9 +496,11 @@ const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {

static int __create_shmem(struct drm_i915_private *i915,
			  struct drm_gem_object *obj,
			  resource_size_t size)
			  resource_size_t size,
			  unsigned int flags)
{
	unsigned long flags = VM_NORESERVE;
	unsigned long shmem_flags = VM_NORESERVE;
	struct vfsmount *huge_mnt;
	struct file *filp;

	drm_gem_private_object_init(&i915->drm, obj, size);
@@ -515,11 +519,12 @@ static int __create_shmem(struct drm_i915_private *i915,
	if (BITS_PER_LONG == 64 && size > MAX_LFS_FILESIZE)
		return -E2BIG;

	if (i915->mm.gemfs)
		filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
						 flags);
	huge_mnt = drm_gem_get_huge_mnt(&i915->drm);
	if (!(flags & I915_BO_ALLOC_NOTHP) && huge_mnt)
		filp = shmem_file_setup_with_mnt(huge_mnt, "i915", size,
						 shmem_flags);
	else
		filp = shmem_file_setup("i915", size, flags);
		filp = shmem_file_setup("i915", size, shmem_flags);
	if (IS_ERR(filp))
		return PTR_ERR(filp);

@@ -548,7 +553,7 @@ static int shmem_object_init(struct intel_memory_region *mem,
	gfp_t mask;
	int ret;

	ret = __create_shmem(i915, &obj->base, size);
	ret = __create_shmem(i915, &obj->base, size, flags);
	if (ret)
		return ret;

@@ -644,21 +649,40 @@ i915_gem_object_create_shmem_from_data(struct drm_i915_private *i915,

static int init_shmem(struct intel_memory_region *mem)
{
	i915_gemfs_init(mem->i915);
	intel_memory_region_set_name(mem, "system");
	struct drm_i915_private *i915 = mem->i915;

	return 0; /* We have fallback to the kernel mnt if gemfs init failed. */
}
	/*
	 * By creating our own shmemfs mountpoint, we can pass in
	 * mount flags that better match our usecase.
	 *
	 * One example, although it is probably better with a per-file
	 * control, is selecting huge page allocations ("huge=within_size").
	 * However, we only do so on platforms which benefit from it, or to
	 * offset the overhead of iommu lookups, where with latter it is a net
	 * win even on platforms which would otherwise see some performance
	 * regressions such a slow reads issue on Broadwell and Skylake.
	 */

static int release_shmem(struct intel_memory_region *mem)
{
	i915_gemfs_fini(mem->i915);
	return 0;
	if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915))
		goto no_thp;

	drm_gem_huge_mnt_create(&i915->drm, "within_size");
	if (drm_gem_get_huge_mnt(&i915->drm))
		drm_info(&i915->drm, "Using Transparent Hugepages\n");
	else
		drm_notice(&i915->drm,
			   "Transparent Hugepage support is recommended for optimal performance%s\n",
			   GRAPHICS_VER(i915) >= 11 ? " on this platform!" :
						      " when IOMMU is enabled!");

 no_thp:
	intel_memory_region_set_name(mem, "system");

	return 0; /* We have fallback to the kernel mnt if huge mnt failed. */
}

static const struct intel_memory_region_ops shmem_region_ops = {
	.init = init_shmem,
	.release = release_shmem,
	.init_object = shmem_object_init,
};

+0 −71
Original line number Diff line number Diff line
// SPDX-License-Identifier: MIT
/*
 * Copyright © 2017 Intel Corporation
 */

#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/fs_context.h>

#include <drm/drm_print.h>

#include "i915_drv.h"
#include "i915_gemfs.h"
#include "i915_utils.h"

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
	 * mount flags that better match our usecase.
	 *
	 * One example, although it is probably better with a per-file
	 * control, is selecting huge page allocations ("huge=within_size").
	 * However, we only do so on platforms which benefit from it, or to
	 * offset the overhead of iommu lookups, where with latter it is a net
	 * win even on platforms which would otherwise see some performance
	 * regressions such a slow reads issue on Broadwell and Skylake.
	 */

	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 = vfs_parse_fs_string(fc, "source", "tmpfs");
	if (!ret)
		ret = vfs_parse_fs_string(fc, "huge", "within_size");
	if (!ret)
		gemfs = fc_mount_longterm(fc);
	put_fs_context(fc);
	if (ret)
		goto err;

	i915->mm.gemfs = gemfs;
	drm_info(&i915->drm, "Using Transparent Hugepages\n");
	return;

err:
	drm_notice(&i915->drm,
		   "Transparent Hugepage support is recommended for optimal performance%s\n",
		   GRAPHICS_VER(i915) >= 11 ? " on this platform!" :
					      " when IOMMU is enabled!");
}

void i915_gemfs_fini(struct drm_i915_private *i915)
{
	kern_unmount(i915->mm.gemfs);
}
+0 −14
Original line number Diff line number Diff line
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2017 Intel Corporation
 */

#ifndef __I915_GEMFS_H__
#define __I915_GEMFS_H__

struct drm_i915_private;

void i915_gemfs_init(struct drm_i915_private *i915);
void i915_gemfs_fini(struct drm_i915_private *i915);

#endif
Loading