diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2012-10-08 19:30:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-09 03:22:30 -0400 |
commit | 9501d09fa3c4ca18971083dfb0c9aa1afc85f19c (patch) | |
tree | 62c8a0d16e02e0201935ae99921b554148a36bbe | |
parent | 75077afbec1ac89178c1542b23a70d0f960b0aaf (diff) |
thp, s390: thp pagetable pre-allocation for s390
This patch is part of the architecture backend for thp on s390. It
provides the pagetable pre-allocation functions
pgtable_trans_huge_deposit() and pgtable_trans_huge_withdraw(). Unlike
other archs, s390 has no struct page * as pgtable_t, but rather a pointer
to the page table. So instead of saving the pagetable pre- allocation
list info inside the struct page, it is being saved within the pagetable
itself.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Hillf Danton <dhillf@gmail.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/s390/include/asm/pgtable.h | 6 | ||||
-rw-r--r-- | arch/s390/mm/pgtable.c | 38 |
2 files changed, 44 insertions, 0 deletions
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c3f0775e71f1..2c8f00d31cfe 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -1166,6 +1166,12 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) | |||
1166 | #define pte_unmap(pte) do { } while (0) | 1166 | #define pte_unmap(pte) do { } while (0) |
1167 | 1167 | ||
1168 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1168 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
1169 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | ||
1170 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | ||
1171 | |||
1172 | #define __HAVE_ARCH_PGTABLE_WITHDRAW | ||
1173 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); | ||
1174 | |||
1169 | static inline int pmd_trans_splitting(pmd_t pmd) | 1175 | static inline int pmd_trans_splitting(pmd_t pmd) |
1170 | { | 1176 | { |
1171 | return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; | 1177 | return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index a6131d1fe6c0..1ca371a06516 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -883,4 +883,42 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address, | |||
883 | smp_call_function(pmdp_splitting_flush_sync, NULL, 1); | 883 | smp_call_function(pmdp_splitting_flush_sync, NULL, 1); |
884 | } | 884 | } |
885 | } | 885 | } |
886 | |||
887 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable) | ||
888 | { | ||
889 | struct list_head *lh = (struct list_head *) pgtable; | ||
890 | |||
891 | assert_spin_locked(&mm->page_table_lock); | ||
892 | |||
893 | /* FIFO */ | ||
894 | if (!mm->pmd_huge_pte) | ||
895 | INIT_LIST_HEAD(lh); | ||
896 | else | ||
897 | list_add(lh, (struct list_head *) mm->pmd_huge_pte); | ||
898 | mm->pmd_huge_pte = pgtable; | ||
899 | } | ||
900 | |||
901 | pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm) | ||
902 | { | ||
903 | struct list_head *lh; | ||
904 | pgtable_t pgtable; | ||
905 | pte_t *ptep; | ||
906 | |||
907 | assert_spin_locked(&mm->page_table_lock); | ||
908 | |||
909 | /* FIFO */ | ||
910 | pgtable = mm->pmd_huge_pte; | ||
911 | lh = (struct list_head *) pgtable; | ||
912 | if (list_empty(lh)) | ||
913 | mm->pmd_huge_pte = NULL; | ||
914 | else { | ||
915 | mm->pmd_huge_pte = (pgtable_t) lh->next; | ||
916 | list_del(lh); | ||
917 | } | ||
918 | ptep = (pte_t *) pgtable; | ||
919 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
920 | ptep++; | ||
921 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
922 | return pgtable; | ||
923 | } | ||
886 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 924 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |