[PATCH] shmem: avoid huge pages for small files

From: Kirill A. Shutemov
Date: Mon Oct 17 2016 - 07:44:47 EST


Huge pages are detrimental for small file: they causes noticible
overhead on both allocation performance and memory footprint.

This patch aimed to address this issue by avoiding huge pages until
file grown to size of huge page if the filesystem mounted with
huge=within_size option.

This would cover most of the cases where huge pages causes regressions
in performance.

The limit doesn't affect khugepaged behaviour: it still can collapse
pages based on its settings.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx>
---
Documentation/vm/transhuge.txt | 7 ++++++-
mm/shmem.c | 6 ++----
2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/vm/transhuge.txt b/Documentation/vm/transhuge.txt
index 2ec6adb5a4ce..14c911c56f4a 100644
--- a/Documentation/vm/transhuge.txt
+++ b/Documentation/vm/transhuge.txt
@@ -208,11 +208,16 @@ You can control hugepage allocation policy in tmpfs with mount option
- "always":
Attempt to allocate huge pages every time we need a new page;

+ This option can lead to significant overhead if filesystem is used to
+ store small files.
+
- "never":
Do not allocate huge pages;

- "within_size":
- Only allocate huge page if it will be fully within i_size.
+ Only allocate huge page if size of the file more than size of huge
+ page. This helps to avoid overhead for small files.
+
Also respect fadvise()/madvise() hints;

- "advise:
diff --git a/mm/shmem.c b/mm/shmem.c
index ad7813d73ea7..3589d36c7c63 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1681,10 +1681,8 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t index,
case SHMEM_HUGE_NEVER:
goto alloc_nohuge;
case SHMEM_HUGE_WITHIN_SIZE:
- off = round_up(index, HPAGE_PMD_NR);
- i_size = round_up(i_size_read(inode), PAGE_SIZE);
- if (i_size >= HPAGE_PMD_SIZE &&
- i_size >> PAGE_SHIFT >= off)
+ i_size = i_size_read(inode);
+ if (index >= HPAGE_PMD_NR || i_size >= HPAGE_PMD_SIZE)
goto alloc_huge;
/* fallthrough */
case SHMEM_HUGE_ADVISE:
--
Kirill A. Shutemov