1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2017 Intel Corporation 4 */ 5 6 #include <linux/fs.h> 7 #include <linux/mount.h> 8 #include <linux/fs_context.h> 9 10 #include "i915_drv.h" 11 #include "i915_gemfs.h" 12 #include "i915_utils.h" 13 14 static int add_param(struct fs_context *fc, const char *key, const char *val) 15 { 16 return vfs_parse_fs_string(fc, key, val, strlen(val)); 17 } 18 19 void i915_gemfs_init(struct drm_i915_private *i915) 20 { 21 struct file_system_type *type; 22 struct fs_context *fc; 23 struct vfsmount *gemfs; 24 int ret; 25 26 /* 27 * By creating our own shmemfs mountpoint, we can pass in 28 * mount flags that better match our usecase. 29 * 30 * One example, although it is probably better with a per-file 31 * control, is selecting huge page allocations ("huge=within_size"). 32 * However, we only do so on platforms which benefit from it, or to 33 * offset the overhead of iommu lookups, where with latter it is a net 34 * win even on platforms which would otherwise see some performance 35 * regressions such a slow reads issue on Broadwell and Skylake. 36 */ 37 38 if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915)) 39 return; 40 41 if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) 42 goto err; 43 44 type = get_fs_type("tmpfs"); 45 if (!type) 46 goto err; 47 48 fc = fs_context_for_mount(type, SB_KERNMOUNT); 49 if (IS_ERR(fc)) 50 goto err; 51 ret = add_param(fc, "source", "tmpfs"); 52 if (!ret) 53 ret = add_param(fc, "huge", "within_size"); 54 if (!ret) 55 gemfs = fc_mount_longterm(fc); 56 put_fs_context(fc); 57 if (ret) 58 goto err; 59 60 i915->mm.gemfs = gemfs; 61 drm_info(&i915->drm, "Using Transparent Hugepages\n"); 62 return; 63 64 err: 65 drm_notice(&i915->drm, 66 "Transparent Hugepage support is recommended for optimal performance%s\n", 67 GRAPHICS_VER(i915) >= 11 ? " on this platform!" : 68 " when IOMMU is enabled!"); 69 } 70 71 void i915_gemfs_fini(struct drm_i915_private *i915) 72 { 73 kern_unmount(i915->mm.gemfs); 74 } 75