From: Toshi Kani <toshi.kani@hpe.com>
To: akpm@linux-foundation.org
Cc: dan.j.williams@intel.com, mawilcox@microsoft.com,
hughd@google.com, kirill.shutemov@linux.intel.com,
toshi.kani@hpe.com, linux-nvdimm@ml01.01.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 2/2] shmem: call __thp_get_unmapped_area to alloc a pmd-aligned addr
Date: Fri, 9 Sep 2016 16:24:23 -0600 [thread overview]
Message-ID: <1473459863-11287-3-git-send-email-toshi.kani@hpe.com> (raw)
In-Reply-To: <1473459863-11287-1-git-send-email-toshi.kani@hpe.com>
shmem_get_unmapped_area() provides a functionality similar
to __thp_get_unmapped_area() as both allocate a pmd-aligned
address.
Change shmem_get_unmapped_area() to do shm-specific checks
and then call __thp_get_unmapped_area() for allocating
a pmd-aligned address.
link: https://lkml.org/lkml/2016/8/29/620
Suggested-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Toshi Kani <toshi.kani@hpe.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Matthew Wilcox <mawilcox@microsoft.com>
Cc: Dan Williams <dan.j.williams@intel.com>
---
include/linux/huge_mm.h | 10 +++++++
mm/shmem.c | 68 +++++++++--------------------------------------
2 files changed, 23 insertions(+), 55 deletions(-)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 4fca526..1b65924 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -90,6 +90,9 @@ extern unsigned long transparent_hugepage_flags;
extern unsigned long thp_get_unmapped_area(struct file *filp,
unsigned long addr, unsigned long len, unsigned long pgoff,
unsigned long flags);
+extern unsigned long __thp_get_unmapped_area(struct file *filp,
+ unsigned long len, loff_t off, unsigned long flags,
+ unsigned long size);
extern void prep_transhuge_page(struct page *page);
extern void free_transhuge_page(struct page *page);
@@ -176,6 +179,13 @@ static inline void prep_transhuge_page(struct page *page) {}
#define thp_get_unmapped_area NULL
+static inline unsigned long __thp_get_unmapped_area(struct file *filp,
+ unsigned long len, loff_t off, unsigned long flags,
+ unsigned long size)
+{
+ return 0;
+}
+
static inline int
split_huge_page_to_list(struct page *page, struct list_head *list)
{
diff --git a/mm/shmem.c b/mm/shmem.c
index aec5b49..ef27455 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1925,45 +1925,23 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
unsigned long shmem_get_unmapped_area(struct file *file,
- unsigned long uaddr, unsigned long len,
+ unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags)
{
- unsigned long (*get_area)(struct file *,
- unsigned long, unsigned long, unsigned long, unsigned long);
- unsigned long addr;
- unsigned long offset;
- unsigned long inflated_len;
- unsigned long inflated_addr;
- unsigned long inflated_offset;
-
- if (len > TASK_SIZE)
- return -ENOMEM;
-
- get_area = current->mm->get_unmapped_area;
- addr = get_area(file, uaddr, len, pgoff, flags);
+ loff_t off = (loff_t)pgoff << PAGE_SHIFT;
if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE))
- return addr;
- if (IS_ERR_VALUE(addr))
- return addr;
- if (addr & ~PAGE_MASK)
- return addr;
- if (addr > TASK_SIZE - len)
- return addr;
-
+ goto out;
if (shmem_huge == SHMEM_HUGE_DENY)
- return addr;
- if (len < HPAGE_PMD_SIZE)
- return addr;
- if (flags & MAP_FIXED)
- return addr;
+ goto out;
+
/*
* Our priority is to support MAP_SHARED mapped hugely;
* and support MAP_PRIVATE mapped hugely too, until it is COWed.
* But if caller specified an address hint, respect that as before.
*/
- if (uaddr)
- return addr;
+ if (addr)
+ goto out;
if (shmem_huge != SHMEM_HUGE_FORCE) {
struct super_block *sb;
@@ -1977,39 +1955,19 @@ unsigned long shmem_get_unmapped_area(struct file *file,
* for "/dev/zero", to create a shared anonymous object.
*/
if (IS_ERR(shm_mnt))
- return addr;
+ goto out;
sb = shm_mnt->mnt_sb;
}
if (SHMEM_SB(sb)->huge == SHMEM_HUGE_NEVER)
- return addr;
+ goto out;
}
- offset = (pgoff << PAGE_SHIFT) & (HPAGE_PMD_SIZE-1);
- if (offset && offset + len < 2 * HPAGE_PMD_SIZE)
- return addr;
- if ((addr & (HPAGE_PMD_SIZE-1)) == offset)
- return addr;
-
- inflated_len = len + HPAGE_PMD_SIZE - PAGE_SIZE;
- if (inflated_len > TASK_SIZE)
- return addr;
- if (inflated_len < len)
- return addr;
-
- inflated_addr = get_area(NULL, 0, inflated_len, 0, flags);
- if (IS_ERR_VALUE(inflated_addr))
- return addr;
- if (inflated_addr & ~PAGE_MASK)
+ addr = __thp_get_unmapped_area(file, len, off, flags, HPAGE_PMD_SIZE);
+ if (addr)
return addr;
- inflated_offset = inflated_addr & (HPAGE_PMD_SIZE-1);
- inflated_addr += offset - inflated_offset;
- if (inflated_offset > offset)
- inflated_addr += HPAGE_PMD_SIZE;
-
- if (inflated_addr > TASK_SIZE - len)
- return addr;
- return inflated_addr;
+ out:
+ return current->mm->get_unmapped_area(file, addr, len, pgoff, flags);
}
#ifdef CONFIG_NUMA
next prev parent reply other threads:[~2016-09-09 22:25 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-09 22:24 [PATCH 0/2] refactor shmem_get_unmapped_area() Toshi Kani
2016-09-09 22:24 ` [PATCH 1/2] shmem: fix tmpfs to handle the huge= option properly Toshi Kani
2016-09-12 9:59 ` Kirill A. Shutemov
2016-09-22 10:58 ` Aneesh Kumar K.V
2016-09-23 2:33 ` Hugh Dickins
2016-09-09 22:24 ` Toshi Kani [this message]
2016-09-12 10:02 ` [PATCH 2/2] shmem: call __thp_get_unmapped_area to alloc a pmd-aligned addr Kirill A. Shutemov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1473459863-11287-3-git-send-email-toshi.kani@hpe.com \
--to=toshi.kani@hpe.com \
--cc=akpm@linux-foundation.org \
--cc=dan.j.williams@intel.com \
--cc=hughd@google.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-nvdimm@ml01.01.org \
--cc=mawilcox@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®