mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 08:02:27 +02:00
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: Loïc Molinari <loic.molinari@collabora.com> Acked-by: Tvrtko Ursulin <tursulin@ursulin.net> Link: https://patch.msgid.link/20251205182231.194072-6-loic.molinari@collabora.com Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
This commit is contained in:
parent
6e0b1b8201
commit
a8a9a59022
|
|
@ -169,8 +169,7 @@ gem-y += \
|
||||||
gem/i915_gem_ttm_move.o \
|
gem/i915_gem_ttm_move.o \
|
||||||
gem/i915_gem_ttm_pm.o \
|
gem/i915_gem_ttm_pm.o \
|
||||||
gem/i915_gem_userptr.o \
|
gem/i915_gem_userptr.o \
|
||||||
gem/i915_gem_wait.o \
|
gem/i915_gem_wait.o
|
||||||
gem/i915_gemfs.o
|
|
||||||
i915-y += \
|
i915-y += \
|
||||||
$(gem-y) \
|
$(gem-y) \
|
||||||
i915_active.o \
|
i915_active.o \
|
||||||
|
|
|
||||||
|
|
@ -348,12 +348,13 @@ struct drm_i915_gem_object {
|
||||||
*/
|
*/
|
||||||
#define I915_BO_ALLOC_GPU_ONLY BIT(6)
|
#define I915_BO_ALLOC_GPU_ONLY BIT(6)
|
||||||
#define I915_BO_ALLOC_CCS_AUX BIT(7)
|
#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
|
* 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
|
* access if used along with I915_BO_ALLOC_USER. This is mainly to keep
|
||||||
* preallocated framebuffer data intact while transitioning it to i915drmfb.
|
* 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 | \
|
#define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
|
||||||
I915_BO_ALLOC_VOLATILE | \
|
I915_BO_ALLOC_VOLATILE | \
|
||||||
I915_BO_ALLOC_CPU_CLEAR | \
|
I915_BO_ALLOC_CPU_CLEAR | \
|
||||||
|
|
@ -363,9 +364,9 @@ struct drm_i915_gem_object {
|
||||||
I915_BO_ALLOC_GPU_ONLY | \
|
I915_BO_ALLOC_GPU_ONLY | \
|
||||||
I915_BO_ALLOC_CCS_AUX | \
|
I915_BO_ALLOC_CCS_AUX | \
|
||||||
I915_BO_PREALLOC)
|
I915_BO_PREALLOC)
|
||||||
#define I915_BO_READONLY BIT(9)
|
#define I915_BO_READONLY BIT(10)
|
||||||
#define I915_TILING_QUIRK_BIT 10 /* unknown swizzling; do not release! */
|
#define I915_TILING_QUIRK_BIT 11 /* unknown swizzling; do not release! */
|
||||||
#define I915_BO_PROTECTED BIT(11)
|
#define I915_BO_PROTECTED BIT(12)
|
||||||
/**
|
/**
|
||||||
* @mem_flags - Mutable placement-related flags
|
* @mem_flags - Mutable placement-related flags
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,16 @@
|
||||||
#include <linux/uio.h>
|
#include <linux/uio.h>
|
||||||
|
|
||||||
#include <drm/drm_cache.h>
|
#include <drm/drm_cache.h>
|
||||||
|
#include <drm/drm_gem.h>
|
||||||
|
#include <drm/drm_print.h>
|
||||||
|
|
||||||
#include "gem/i915_gem_region.h"
|
#include "gem/i915_gem_region.h"
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
#include "i915_gem_object.h"
|
#include "i915_gem_object.h"
|
||||||
#include "i915_gem_tiling.h"
|
#include "i915_gem_tiling.h"
|
||||||
#include "i915_gemfs.h"
|
|
||||||
#include "i915_scatterlist.h"
|
#include "i915_scatterlist.h"
|
||||||
#include "i915_trace.h"
|
#include "i915_trace.h"
|
||||||
|
#include "i915_utils.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move folios to appropriate lru and release the batch, decrementing the
|
* 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,
|
static int __create_shmem(struct drm_i915_private *i915,
|
||||||
struct drm_gem_object *obj,
|
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;
|
struct file *filp;
|
||||||
|
|
||||||
drm_gem_private_object_init(&i915->drm, obj, size);
|
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)
|
if (BITS_PER_LONG == 64 && size > MAX_LFS_FILESIZE)
|
||||||
return -E2BIG;
|
return -E2BIG;
|
||||||
|
|
||||||
if (i915->mm.gemfs)
|
huge_mnt = drm_gem_get_huge_mnt(&i915->drm);
|
||||||
filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
|
if (!(flags & I915_BO_ALLOC_NOTHP) && huge_mnt)
|
||||||
flags);
|
filp = shmem_file_setup_with_mnt(huge_mnt, "i915", size,
|
||||||
|
shmem_flags);
|
||||||
else
|
else
|
||||||
filp = shmem_file_setup("i915", size, flags);
|
filp = shmem_file_setup("i915", size, shmem_flags);
|
||||||
if (IS_ERR(filp))
|
if (IS_ERR(filp))
|
||||||
return PTR_ERR(filp);
|
return PTR_ERR(filp);
|
||||||
|
|
||||||
|
|
@ -548,7 +553,7 @@ static int shmem_object_init(struct intel_memory_region *mem,
|
||||||
gfp_t mask;
|
gfp_t mask;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = __create_shmem(i915, &obj->base, size);
|
ret = __create_shmem(i915, &obj->base, size, flags);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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)
|
static int init_shmem(struct intel_memory_region *mem)
|
||||||
{
|
{
|
||||||
i915_gemfs_init(mem->i915);
|
struct drm_i915_private *i915 = mem->i915;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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))
|
||||||
|
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");
|
intel_memory_region_set_name(mem, "system");
|
||||||
|
|
||||||
return 0; /* We have fallback to the kernel mnt if gemfs init failed. */
|
return 0; /* We have fallback to the kernel mnt if huge mnt failed. */
|
||||||
}
|
|
||||||
|
|
||||||
static int release_shmem(struct intel_memory_region *mem)
|
|
||||||
{
|
|
||||||
i915_gemfs_fini(mem->i915);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct intel_memory_region_ops shmem_region_ops = {
|
static const struct intel_memory_region_ops shmem_region_ops = {
|
||||||
.init = init_shmem,
|
.init = init_shmem,
|
||||||
.release = release_shmem,
|
|
||||||
.init_object = shmem_object_init,
|
.init_object = shmem_object_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
/* 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
|
|
||||||
|
|
@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object *
|
||||||
|
|
||||||
static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
|
static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
|
||||||
{
|
{
|
||||||
return i915->mm.gemfs && has_transparent_hugepage();
|
return !!drm_gem_get_huge_mnt(&i915->drm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct drm_i915_gem_object *
|
static struct drm_i915_gem_object *
|
||||||
|
|
@ -1761,7 +1761,6 @@ static int igt_tmpfs_fallback(void *arg)
|
||||||
struct drm_i915_private *i915 = arg;
|
struct drm_i915_private *i915 = arg;
|
||||||
struct i915_address_space *vm;
|
struct i915_address_space *vm;
|
||||||
struct i915_gem_context *ctx;
|
struct i915_gem_context *ctx;
|
||||||
struct vfsmount *gemfs = i915->mm.gemfs;
|
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
struct i915_vma *vma;
|
struct i915_vma *vma;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
|
|
@ -1779,15 +1778,8 @@ static int igt_tmpfs_fallback(void *arg)
|
||||||
}
|
}
|
||||||
vm = i915_gem_context_get_eb_vm(ctx);
|
vm = i915_gem_context_get_eb_vm(ctx);
|
||||||
|
|
||||||
/*
|
obj = i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
|
||||||
* Make sure that we don't burst into a ball of flames upon falling back
|
PAGE_SIZE, 0, I915_BO_ALLOC_NOTHP);
|
||||||
* to tmpfs, which we rely on if on the off-chance we encounter a failure
|
|
||||||
* when setting up gemfs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
i915->mm.gemfs = NULL;
|
|
||||||
|
|
||||||
obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
|
|
||||||
if (IS_ERR(obj)) {
|
if (IS_ERR(obj)) {
|
||||||
err = PTR_ERR(obj);
|
err = PTR_ERR(obj);
|
||||||
goto out_restore;
|
goto out_restore;
|
||||||
|
|
@ -1819,7 +1811,6 @@ static int igt_tmpfs_fallback(void *arg)
|
||||||
out_put:
|
out_put:
|
||||||
i915_gem_object_put(obj);
|
i915_gem_object_put(obj);
|
||||||
out_restore:
|
out_restore:
|
||||||
i915->mm.gemfs = gemfs;
|
|
||||||
|
|
||||||
i915_vm_put(vm);
|
i915_vm_put(vm);
|
||||||
out:
|
out:
|
||||||
|
|
|
||||||
|
|
@ -141,11 +141,6 @@ struct i915_gem_mm {
|
||||||
*/
|
*/
|
||||||
atomic_t free_count;
|
atomic_t free_count;
|
||||||
|
|
||||||
/**
|
|
||||||
* tmpfs instance used for shmem backed objects
|
|
||||||
*/
|
|
||||||
struct vfsmount *gemfs;
|
|
||||||
|
|
||||||
struct intel_memory_region *regions[INTEL_REGION_UNKNOWN];
|
struct intel_memory_region *regions[INTEL_REGION_UNKNOWN];
|
||||||
|
|
||||||
struct notifier_block oom_notifier;
|
struct notifier_block oom_notifier;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user