From patchwork Tue May 16 08:29:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Auld X-Patchwork-Id: 9728547 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B53006028A for ; Tue, 16 May 2017 08:30:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A534E289EA for ; Tue, 16 May 2017 08:30:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A1FD28A01; Tue, 16 May 2017 08:30:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 01EBD289EA for ; Tue, 16 May 2017 08:30:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 794116E2D6; Tue, 16 May 2017 08:30:05 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 29A7E6E2D6 for ; Tue, 16 May 2017 08:30:01 +0000 (UTC) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP; 16 May 2017 01:30:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.38,348,1491289200"; d="scan'208"; a="1130912736" Received: from koreilly-mobl1.ger.corp.intel.com (HELO mwahaha.ger.corp.intel.com) ([10.252.21.88]) by orsmga001.jf.intel.com with ESMTP; 16 May 2017 01:29:59 -0700 From: Matthew Auld To: intel-gfx@lists.freedesktop.org Date: Tue, 16 May 2017 09:29:37 +0100 Message-Id: <20170516082948.28090-7-matthew.auld@intel.com> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170516082948.28090-1-matthew.auld@intel.com> References: <20170516082948.28090-1-matthew.auld@intel.com> Cc: Dave Hansen , Hugh Dickins , linux-mm@kvack.org Subject: [Intel-gfx] [PATCH 06/17] mm/shmem: expose driver overridable huge option X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP In i915 we are aiming to support huge GTT pages for the GPU, and to complement this we also want to enable THP for our shmem backed objects. Even though THP is supported in shmemfs it can only be enabled through the huge= mount option, but for users of the kernel mounted shm_mnt like i915, we are a little stuck. There is the sysfs knob shmem_enabled to either forcefully enable/disable the feature, but that seems to only be useful for testing purposes. What we propose is to expose a driver overridable huge option as part of shmem_inode_info to control the use of THP for a given mapping. Signed-off-by: Matthew Auld Cc: Joonas Lahtinen Cc: Dave Hansen Cc: Daniel Vetter Cc: Hugh Dickins Cc: linux-mm@kvack.org --- include/linux/shmem_fs.h | 20 ++++++++++++++++++++ mm/shmem.c | 37 +++++++++++++++---------------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a7d6bd2a918f..4cfdb2e8e1d8 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -21,8 +21,28 @@ struct shmem_inode_info { struct shared_policy policy; /* NUMA memory alloc policy */ struct simple_xattrs xattrs; /* list of xattrs */ struct inode vfs_inode; + unsigned char huge; /* driver override sbinfo->huge */ }; +/* + * Definitions for "huge tmpfs": tmpfs mounted with the huge= option + * + * SHMEM_HUGE_NEVER: + * disables huge pages for the mount; + * SHMEM_HUGE_ALWAYS: + * enables huge pages for the mount; + * SHMEM_HUGE_WITHIN_SIZE: + * only allocate huge pages if the page will be fully within i_size, + * also respect fadvise()/madvise() hints; + * SHMEM_HUGE_ADVISE: + * only allocate huge pages if requested with fadvise()/madvise(); + */ + +#define SHMEM_HUGE_NEVER 0 +#define SHMEM_HUGE_ALWAYS 1 +#define SHMEM_HUGE_WITHIN_SIZE 2 +#define SHMEM_HUGE_ADVISE 3 + struct shmem_sb_info { unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ diff --git a/mm/shmem.c b/mm/shmem.c index e67d6ba4e98e..4fa042694957 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -346,25 +346,6 @@ static bool shmem_confirm_swap(struct address_space *mapping, } /* - * Definitions for "huge tmpfs": tmpfs mounted with the huge= option - * - * SHMEM_HUGE_NEVER: - * disables huge pages for the mount; - * SHMEM_HUGE_ALWAYS: - * enables huge pages for the mount; - * SHMEM_HUGE_WITHIN_SIZE: - * only allocate huge pages if the page will be fully within i_size, - * also respect fadvise()/madvise() hints; - * SHMEM_HUGE_ADVISE: - * only allocate huge pages if requested with fadvise()/madvise(); - */ - -#define SHMEM_HUGE_NEVER 0 -#define SHMEM_HUGE_ALWAYS 1 -#define SHMEM_HUGE_WITHIN_SIZE 2 -#define SHMEM_HUGE_ADVISE 3 - -/* * Special values. * Only can be set via /sys/kernel/mm/transparent_hugepage/shmem_enabled: * @@ -1715,6 +1696,8 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, swap_free(swap); } else { + unsigned char sbinfo_huge = sbinfo->huge; + if (vma && userfaultfd_missing(vma)) { *fault_type = handle_userfault(vmf, VM_UFFD_MISSING); return 0; @@ -1727,7 +1710,10 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, goto alloc_nohuge; if (shmem_huge == SHMEM_HUGE_FORCE) goto alloc_huge; - switch (sbinfo->huge) { + /* driver override sbinfo->huge */ + if (info->huge) + sbinfo_huge = info->huge; + switch (sbinfo_huge) { loff_t i_size; pgoff_t off; case SHMEM_HUGE_NEVER: @@ -2032,10 +2018,13 @@ unsigned long shmem_get_unmapped_area(struct file *file, if (shmem_huge != SHMEM_HUGE_FORCE) { struct super_block *sb; + unsigned char sbinfo_huge = 0; if (file) { VM_BUG_ON(file->f_op != &shmem_file_operations); sb = file_inode(file)->i_sb; + /* driver override sbinfo->huge */ + sbinfo_huge = SHMEM_I(file_inode(file))->huge; } else { /* * Called directly from mm/mmap.c, or drivers/char/mem.c @@ -2045,7 +2034,8 @@ unsigned long shmem_get_unmapped_area(struct file *file, return addr; sb = shm_mnt->mnt_sb; } - if (SHMEM_SB(sb)->huge == SHMEM_HUGE_NEVER) + if (SHMEM_SB(sb)->huge == SHMEM_HUGE_NEVER && + sbinfo_huge == SHMEM_HUGE_NEVER) return addr; } @@ -4031,6 +4021,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma) { struct inode *inode = file_inode(vma->vm_file); struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + unsigned char sbinfo_huge = sbinfo->huge; loff_t i_size; pgoff_t off; @@ -4038,7 +4029,9 @@ bool shmem_huge_enabled(struct vm_area_struct *vma) return true; if (shmem_huge == SHMEM_HUGE_DENY) return false; - switch (sbinfo->huge) { + if (SHMEM_I(inode)->huge) + sbinfo_huge = SHMEM_I(inode)->huge; + switch (sbinfo_huge) { case SHMEM_HUGE_NEVER: return false; case SHMEM_HUGE_ALWAYS: