Currently the config ARCH_WANT_GENERAL_HUGETLB enabled functions like
'huge_pte_alloc' and 'huge_pte_offset' dont take into account HugeTLB
page implementation at the PGD level. This is also true for functions
like 'follow_page_mask' which is called from move_pages() system call.
This lack of PGD level huge page support prohibits some architectures
to use these generic HugeTLB functions.
This change adds the required PGD based implementation awareness and
with that, more architectures like POWER which implements 16GB pages
at the PGD level along with the 16MB pages at the PMD level can now
use ARCH_WANT_GENERAL_HUGETLB config option.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/hugetlb.h | 3 +++
mm/gup.c | 6 ++++++
mm/hugetlb.c | 20 ++++++++++++++++++++
3 files changed, 29 insertions(+)
Currently the function 'huge_pte_offset' has just got one version for all
possible configurations and platforms. This change splits that function
into two versions, first one for ARCH_WANT_GENERAL_HUGETLB implementation
and the other one for everything else. This change is again one of the
prerequisites towards enabling ARCH_WANT_GENERAL_ HUGETLB config option
on POWER platform.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/mm/hugetlbpage.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
follow_huge_(pmd|pud|pgd) functions are used to walk the page table and
fetch the page struct during 'follow_page_mask' call. There are possible
race conditions faced by these functions which arise out of simultaneous
calls of move_pages() and freeing of huge pages. This was fixed partly
by the previous commit e66f17ff7177 ("mm/hugetlb: take page table lock
in follow_huge_pmd()") for only PMD based huge pages.
After implementing similar logic, functions like follow_huge_(pud|pgd)
are now safe from above mentioned race conditions and also can support
FOLL_GET. Generic version of the function 'follow_huge_addr' has been
left as it is and its upto the architecture to decide on it.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/mm.h | 33 +++++++++++++++++++++++++++
mm/hugetlb.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 91 insertions(+), 9 deletions(-)
The commit 091d0d55b286 ("shm: fix null pointer deref when userspace
specifies invalid hugepage size") had replaced MAP_HUGE_MASK with
SHM_HUGE_MASK. Though both of them contain the same numeric value of
0x3f, MAP_HUGE_MASK flag sounds more appropriate than the other one
in the context. Hence change it back.
Signed-off-by: Anshuman Khandual <redacted>
---
mm/mmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
This change enables the config option ARCH_ENABLE_HUGEPAGE_MIGRATION
depending on whether the platform has got ARCH_WANT_GENERAL_HUGETLB
or not along with config option MIGRATION. In turn, it turns on the
'hugepage_migration_supported' function which is checked for feature
presence during HugeTLB page migration and clears the way.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/Kconfig | 4 ++++
1 file changed, 4 insertions(+)
Arch override function 'follow_huge_addr' is called from 'follow_page_mask'
looking out for the associated page struct. Right now, it does not support
the FOLL_GET option.
With ARCH_WANTS_GENERAL_HUGETLB, we will need function 'follow_page_mask'
to use generic 'follow_huge_*' functions instead of the arch overrides. So,
here it modifies 'follow_huge_addr' function to return ERR_PTR(-EINVAL)
when ARCH_WANT_GENERAL_HUGETLB option is enabled. This also hides away all
the arch specific 'follow_huge_*' overrides allowing it to fall back on the
generic 'follow_huge_*' functions instead.
While here, this also implements the function 'pte_huge' which is required
by the generic call 'huge_pte_alloc'.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/include/asm/book3s/64/hash-64k.h | 10 ++++++++++
arch/powerpc/mm/hugetlbpage.c | 14 ++++++++++++++
2 files changed, 24 insertions(+)
Currently the function 'huge_pte_alloc' has got two versions, one for the
BOOK3S server and the other one for the BOOK3E embedded platforms. This
change splits only the BOOK3S server version into two parts, one for the
ARCH_WANT_GENERAL_HUGETLB config implementation and the other one for
everything else. This change is one of the prerequisites towards enabling
ARCH_WANT_GENERAL_HUGETLB config option on POWER platform.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/mm/hugetlbpage.c | 67 +++++++++++++++++++++++++++----------------
1 file changed, 43 insertions(+), 24 deletions(-)
This enables ARCH_WANT_GENERAL_HUGETLB config option only for BOOK3S
platforms with 64K page size implementation. Existing arch specific
functions for ARCH_WANT_GENERAL_HUGETLB config like 'huge_pte_alloc'
and 'huge_pte_offset' are no longer required and are removed with
this change.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/Kconfig | 4 +++
arch/powerpc/mm/hugetlbpage.c | 58 -------------------------------------------
2 files changed, 4 insertions(+), 58 deletions(-)
This adds two tests for memory page migration. One for normal page
migration which works for both 4K or 64K base page size kernel and
the other one is for huge page migration which works only on 64K
base page sized 16MB huge page implemention at the PMD level.
Signed-off-by: Anshuman Khandual <redacted>
---
tools/testing/selftests/powerpc/mm/Makefile | 14 +-
.../selftests/powerpc/mm/hugepage-migration.c | 30 +++
tools/testing/selftests/powerpc/mm/migration.h | 205 +++++++++++++++++++++
.../testing/selftests/powerpc/mm/page-migration.c | 33 ++++
tools/testing/selftests/powerpc/mm/run_mmtests | 104 +++++++++++
5 files changed, 381 insertions(+), 5 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/mm/hugepage-migration.c
create mode 100644 tools/testing/selftests/powerpc/mm/migration.h
create mode 100644 tools/testing/selftests/powerpc/mm/page-migration.c
create mode 100755 tools/testing/selftests/powerpc/mm/run_mmtests
@@ -0,0 +1,30 @@+/*+*Copyright(C)2015,AnshumanKhandual,IBMCorporation.+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseversion2aspublished+*bytheFreeSoftwareFoundation.+*/+#include"migration.h"++staticinthugepage_migration(void)+{+intret=0;++if((unsignedlong)getpagesize()==0x1000)+printf("Running on base page size 4K\n");++if((unsignedlong)getpagesize()==0x10000)+printf("Running on base page size 64K\n");++ret=test_huge_migration(16*MEM_MB);+ret=test_huge_migration(256*MEM_MB);+ret=test_huge_migration(512*MEM_MB);++returnret;+}++intmain(void)+{+returntest_harness(hugepage_migration,"hugepage_migration");+}
@@ -0,0 +1,33 @@+/*+*Copyright(C)2015,AnshumanKhandual,IBMCorporation.+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseversion2aspublished+*bytheFreeSoftwareFoundation.+*/+#include"migration.h"++staticintpage_migration(void)+{+intret=0;++if((unsignedlong)getpagesize()==0x1000)+printf("Running on base page size 4K\n");++if((unsignedlong)getpagesize()==0x10000)+printf("Running on base page size 64K\n");++ret=test_migration(4*MEM_MB);+ret=test_migration(64*MEM_MB);+ret=test_migration(256*MEM_MB);+ret=test_migration(512*MEM_MB);+ret=test_migration(1*MEM_GB);+ret=test_migration(2*MEM_GB);++returnret;+}++intmain(void)+{+returntest_harness(page_migration,"page_migration");+}
This just adds user space exported ABI definitions for both 16MB and
16GB non default huge page sizes to be used with mmap() system call.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/include/uapi/asm/mman.h | 3 +++
1 file changed, 3 insertions(+)
The commit 091d0d55b286 ("shm: fix null pointer deref when userspace
specifies invalid hugepage size") had replaced MAP_HUGE_MASK with
SHM_HUGE_MASK. Though both of them contain the same numeric value of
0x3f, MAP_HUGE_MASK flag sounds more appropriate than the other one
in the context. Hence change it back.
Signed-off-by: Anshuman Khandual <redacted>
Currently the config ARCH_WANT_GENERAL_HUGETLB enabled functions like
'huge_pte_alloc' and 'huge_pte_offset' dont take into account HugeTLB
page implementation at the PGD level. This is also true for functions
like 'follow_page_mask' which is called from move_pages() system call.
This lack of PGD level huge page support prohibits some architectures
to use these generic HugeTLB functions.
From what I know of move_pages(), it will always call follow_page_mask()
with FOLL_GET (I could be wrong here) and the implementation below
returns NULL for follow_huge_pgd().
quoted hunk
This change adds the required PGD based implementation awareness and
with that, more architectures like POWER which implements 16GB pages
at the PGD level along with the 16MB pages at the PMD level can now
use ARCH_WANT_GENERAL_HUGETLB config option.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/hugetlb.h | 3 +++
mm/gup.c | 6 ++++++
mm/hugetlb.c | 20 ++++++++++++++++++++
3 files changed, 29 insertions(+)
mm/hugetlb.c:4395:8: warning: assignment makes pointer from integer without a cast
page = pgd_page(*pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
^
cc1: some warnings being treated as errors
vim +/pgd_page +4395 mm/hugetlb.c
4389 * make sure that the address range covered by this pgd is not
4390 * unmapped from other threads.
4391 */
4392 if (!pgd_huge(*pgd))
4393 goto out;
4394 if (pgd_present(*pgd)) {
follow_huge_(pmd|pud|pgd) functions are used to walk the page table and
fetch the page struct during 'follow_page_mask' call. There are possible
race conditions faced by these functions which arise out of simultaneous
calls of move_pages() and freeing of huge pages. This was fixed partly
by the previous commit e66f17ff7177 ("mm/hugetlb: take page table lock
in follow_huge_pmd()") for only PMD based huge pages.
After implementing similar logic, functions like follow_huge_(pud|pgd)
are now safe from above mentioned race conditions and also can support
FOLL_GET. Generic version of the function 'follow_huge_addr' has been
left as it is and its upto the architecture to decide on it.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/mm.h | 33 +++++++++++++++++++++++++++
mm/hugetlb.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 91 insertions(+), 9 deletions(-)
Do we still use USE_SPLIT_PMD_PTLOCKS? I think its good enough. with pgd's
we are likely to use the same locks and the split nature may not be really
split.
mm/hugetlb.c:4360:3: error: implicit declaration of function 'pud_page' [-Werror=implicit-function-declaration]
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c:4360:8: warning: assignment makes pointer from integer without a cast
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c: In function 'follow_huge_pgd':
mm/hugetlb.c:4395:3: error: implicit declaration of function 'pgd_page' [-Werror=implicit-function-declaration]
page = pgd_page(*pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c:4395:8: warning: assignment makes pointer from integer without a cast
page = pgd_page(*pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
^
cc1: some warnings being treated as errors
vim +/pud_page +4360 mm/hugetlb.c
4354 * make sure that the address range covered by this pud is not
4355 * unmapped from other threads.
4356 */
4357 if (!pud_huge(*pud))
4358 goto out;
4359 if (pud_present(*pud)) {
Currently the config ARCH_WANT_GENERAL_HUGETLB enabled functions like
'huge_pte_alloc' and 'huge_pte_offset' dont take into account HugeTLB
page implementation at the PGD level. This is also true for functions
like 'follow_page_mask' which is called from move_pages() system call.
This lack of PGD level huge page support prohibits some architectures
to use these generic HugeTLB functions.
From what I know of move_pages(), it will always call follow_page_mask()
with FOLL_GET (I could be wrong here) and the implementation below
returns NULL for follow_huge_pgd().
You are right. This patch makes ARCH_WANT_GENERAL_HUGETLB functions aware
of PGD implementation so that we can do all transactions on 16GB pages
using these function instead of the present arch overrides. But that also
requires follow_page_mask() changes for every other access to the page
than the migrate_pages() usage.
But yes, we dont support migrate_pages() on PGD based pages yet, hence
it just returns NULL in that case. May be the commit message needs to
reflect this.
quoted
This change adds the required PGD based implementation awareness and
with that, more architectures like POWER which implements 16GB pages
at the PGD level along with the 16MB pages at the PMD level can now
use ARCH_WANT_GENERAL_HUGETLB config option.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/hugetlb.h | 3 +++
mm/gup.c | 6 ++++++
mm/hugetlb.c | 20 ++++++++++++++++++++
3 files changed, 29 insertions(+)
follow_huge_(pmd|pud|pgd) functions are used to walk the page table and
fetch the page struct during 'follow_page_mask' call. There are possible
race conditions faced by these functions which arise out of simultaneous
calls of move_pages() and freeing of huge pages. This was fixed partly
by the previous commit e66f17ff7177 ("mm/hugetlb: take page table lock
in follow_huge_pmd()") for only PMD based huge pages.
After implementing similar logic, functions like follow_huge_(pud|pgd)
are now safe from above mentioned race conditions and also can support
FOLL_GET. Generic version of the function 'follow_huge_addr' has been
left as it is and its upto the architecture to decide on it.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/mm.h | 33 +++++++++++++++++++++++++++
mm/hugetlb.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 91 insertions(+), 9 deletions(-)
Do we still use USE_SPLIT_PMD_PTLOCKS? I think its good enough. with pgd's
we are likely to use the same locks and the split nature may not be really
split.
Sorry Balbir, did not get what you asked. Can you please elaborate on
this ?
All errors (new ones prefixed by >>):
mm/hugetlb.c: In function 'follow_huge_pud':
quoted
quoted
quoted
quoted
mm/hugetlb.c:4360:3: error: implicit declaration of function 'pud_page' [-Werror=implicit-function-declaration]
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c:4360:8: warning: assignment makes pointer from integer without a cast
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c: In function 'follow_huge_pgd':
mm/hugetlb.c:4395:3: error: implicit declaration of function 'pgd_page' [-Werror=implicit-function-declaration]
page = pgd_page(*pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
Both the build errors here are because of the fact that pgd_page() is
not available for some platforms and config options. It got missed as
I ran only powerpc config options for build test purpose. My bad, will
fix it.
Currently the config ARCH_WANT_GENERAL_HUGETLB enabled functions like
'huge_pte_alloc' and 'huge_pte_offset' dont take into account HugeTLB
page implementation at the PGD level. This is also true for functions
like 'follow_page_mask' which is called from move_pages() system call.
This lack of PGD level huge page support prohibits some architectures
to use these generic HugeTLB functions.
From what I know of move_pages(), it will always call follow_page_mask()
with FOLL_GET (I could be wrong here) and the implementation below
returns NULL for follow_huge_pgd().
You are right. This patch makes ARCH_WANT_GENERAL_HUGETLB functions aware
of PGD implementation so that we can do all transactions on 16GB pages
using these function instead of the present arch overrides. But that also
requires follow_page_mask() changes for every other access to the page
than the migrate_pages() usage.
But yes, we dont support migrate_pages() on PGD based pages yet, hence
it just returns NULL in that case. May be the commit message needs to
reflect this.
The next commit actually changes follow_huge_pud|pgd() functions to
support FOLL_GET and PGD based huge page migration.
follow_huge_(pmd|pud|pgd) functions are used to walk the page table and
fetch the page struct during 'follow_page_mask' call. There are possible
race conditions faced by these functions which arise out of simultaneous
calls of move_pages() and freeing of huge pages. This was fixed partly
by the previous commit e66f17ff7177 ("mm/hugetlb: take page table lock
in follow_huge_pmd()") for only PMD based huge pages.
After implementing similar logic, functions like follow_huge_(pud|pgd)
are now safe from above mentioned race conditions and also can support
FOLL_GET. Generic version of the function 'follow_huge_addr' has been
left as it is and its upto the architecture to decide on it.
Signed-off-by: Anshuman Khandual <redacted>
---
include/linux/mm.h | 33 +++++++++++++++++++++++++++
mm/hugetlb.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 91 insertions(+), 9 deletions(-)
Do we still use USE_SPLIT_PMD_PTLOCKS? I think its good enough. with pgd's
we are likely to use the same locks and the split nature may not be really
split.
Sorry Balbir, did not get what you asked. Can you please elaborate on
this ?
What I meant is that do we need SPLIT_PUD_PTLOCKS for example? I don't think we do
Balbir
Currently the function 'huge_pte_alloc' has got two versions, one for the
BOOK3S server and the other one for the BOOK3E embedded platforms. This
change splits only the BOOK3S server version into two parts, one for the
ARCH_WANT_GENERAL_HUGETLB config implementation and the other one for
everything else. This change is one of the prerequisites towards enabling
ARCH_WANT_GENERAL_HUGETLB config option on POWER platform.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/mm/hugetlbpage.c | 67 +++++++++++++++++++++++++++----------------
1 file changed, 43 insertions(+), 24 deletions(-)
From: Michal Hocko <mhocko@kernel.org> Date: 2016-04-13 07:54:23
On Thu 07-04-16 11:07:35, Anshuman Khandual wrote:
The commit 091d0d55b286 ("shm: fix null pointer deref when userspace
specifies invalid hugepage size") had replaced MAP_HUGE_MASK with
SHM_HUGE_MASK. Though both of them contain the same numeric value of
0x3f, MAP_HUGE_MASK flag sounds more appropriate than the other one
in the context. Hence change it back.
Yes, SHM_HUGE_MASK mixing with MAP_HUGE_SHIFT is not only misleading
it might bite us later should any of the two change.
--
2.1.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
Currently the function 'huge_pte_alloc' has got two versions, one for the
BOOK3S server and the other one for the BOOK3E embedded platforms. This
change splits only the BOOK3S server version into two parts, one for the
ARCH_WANT_GENERAL_HUGETLB config implementation and the other one for
everything else. This change is one of the prerequisites towards enabling
ARCH_WANT_GENERAL_HUGETLB config option on POWER platform.
Signed-off-by: Anshuman Khandual <redacted>
---
arch/powerpc/mm/hugetlbpage.c | 67 +++++++++++++++++++++++++++----------------
1 file changed, 43 insertions(+), 24 deletions(-)
@@ -182,6 +176,31 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long szreturnhugepte_offset(*hpdp,addr,pdshift);}+#else /* CONFIG_ARCH_WANT_GENERAL_HUGETLB */+pte_t*huge_pte_alloc(structmm_struct*mm,unsignedlongaddr,unsignedlongsz)
This is confusing, aren't we using the one from mm/hugetlb.c?
We are using huge_pte_alloc() from mm/hugetlb.c only when we have
CONFIG_ARCH_WANT_GENERAL_HUGETLB enabled. For every thing else we
use the definition here for BOOK3S platforms.
All errors (new ones prefixed by >>):
mm/hugetlb.c: In function 'follow_huge_pud':
quoted
quoted
quoted
quoted
quoted
quoted
quoted
quoted
mm/hugetlb.c:4360:3: error: implicit declaration of function 'pud_page' [-Werror=implicit-function-declaration]
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c:4360:8: warning: assignment makes pointer from integer without a cast
page = pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
^
mm/hugetlb.c: In function 'follow_huge_pgd':
mm/hugetlb.c:4395:3: error: implicit declaration of function 'pgd_page' [-Werror=implicit-function-declaration]
page = pgd_page(*pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
Both the build errors here are because of the fact that pgd_page() is
not available for some platforms and config options. It got missed as
I ran only powerpc config options for build test purpose. My bad, will
fix it.
The following change seems to fix the build problem on S390 but will
require some inputs from S390 maintainers regarding the functional
correctness of the patch.
The following change seems to fix the build problem on SPARC but will
require some inputs from SPARC maintainers regarding the functional
correctness of the patch.
diff --git a/arch/sparc/include/asm/pgtable_64.h
b/arch/sparc/include/asm/pgtable_64.h
index f089cfa..7b7e6a0 100644
This patch series enables HugeTLB page migration on POWER platform.
This series has some core VM changes (patch 1, 2, 3) and some powerpc
specific changes (patch 4, 5, 6, 7, 8, 9, 10). Comments, suggestions
and inputs are welcome.
Anshuman Khandual (10):
mm/mmap: Replace SHM_HUGE_MASK with MAP_HUGE_MASK inside mmap_pgoff
mm/hugetlb: Add PGD based implementation awareness
mm/hugetlb: Protect follow_huge_(pud|pgd) functions from race
Hugh/Mel/Naoya/Andrew,
Andrew had already reviewed the changes in the first two patches during
the RFC phase and was okay with them. Could you please review the third
patch here as well and let me know your inputs/suggestions. Currently
the third patch has got build failures on SPARC and S390 platforms
(details of which are on the thread with possible fixes). Thank you.