Skip to content

Commit 10dd5a0

Browse files
gerald-schaeferAlexander Gordeev
authored andcommitted
s390/mm: Enable THP_SWAP and THP_MIGRATION
After hugetlbfs PTE_MARKER support for s390 introduced region-third and segment table swap entries, it is now possible to also enable THP_SWAP and THP_MIGRATION for s390. s390 has different layout for PTE and region / segment table entries (RSTE). This is also true for swap entries, and their swap type and offset encoding. For hugetlbfs PTE_MARKER support, s390 has internal __swp_type_rste() and __swp_offset_rste() helpers to correctly handle RSTE swap entries. But common swap code does not know about this difference, and only uses __swp_type(), __swp_offset() and __swp_entry() helpers for conversion between arch-dependent and arch-independent representation of swp_entry_t for all pagetable levels. On s390, those helpers only work for PTE swap entries. Therefore, implement __pmd_to_swp_entry() to build a fake PTE swap entry and return the arch-dependent representation of that. Correspondingly, implement __swp_entry_to_pmd() to convert that into a proper PMD swap entry again. With this, the arch-dependent swp_entry_t representation will always look like a PTE swap entry in common code. This is somewhat similar to fake PTEs in hugetlbfs code for s390, but only requires conversion of the swap type and offset, and not all the possible PTE bits. For PMD swap entry SOFT_DIRTY handling, use the same helpers as for normal PMDs. Similar to PTEs, the SOFT_DIRTY bit location is the same for swap and normal entries. Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Gerald Schaefer <[email protected]> Signed-off-by: Alexander Gordeev <[email protected]>
1 parent ccb0aa0 commit 10dd5a0

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

arch/s390/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ config S390
7474
select ARCH_ENABLE_MEMORY_HOTPLUG if SPARSEMEM
7575
select ARCH_ENABLE_MEMORY_HOTREMOVE
7676
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
77+
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
7778
select ARCH_HAS_CPU_FINALIZE_INIT
7879
select ARCH_HAS_CURRENT_STACK_POINTER
7980
select ARCH_HAS_DEBUG_VIRTUAL
@@ -150,6 +151,7 @@ config S390
150151
select ARCH_WANT_KERNEL_PMD_MKWRITE
151152
select ARCH_WANT_LD_ORPHAN_WARN
152153
select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
154+
select ARCH_WANTS_THP_SWAP
153155
select BUILDTIME_TABLE_SORT
154156
select CLONE_BACKWARDS2
155157
select DCACHE_WORD_ACCESS if !KMSAN

arch/s390/include/asm/pgtable.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,12 @@ static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd)
963963
return clear_pmd_bit(pmd, __pgprot(_SEGMENT_ENTRY_SOFT_DIRTY));
964964
}
965965

966+
#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
967+
#define pmd_swp_soft_dirty(pmd) pmd_soft_dirty(pmd)
968+
#define pmd_swp_mksoft_dirty(pmd) pmd_mksoft_dirty(pmd)
969+
#define pmd_swp_clear_soft_dirty(pmd) pmd_clear_soft_dirty(pmd)
970+
#endif
971+
966972
/*
967973
* query functions pte_write/pte_dirty/pte_young only work if
968974
* pte_present() is true. Undefined behaviour if not..
@@ -1979,6 +1985,45 @@ static inline unsigned long __swp_offset_rste(swp_entry_t entry)
19791985

19801986
#define __rste_to_swp_entry(rste) ((swp_entry_t) { rste })
19811987

1988+
/*
1989+
* s390 has different layout for PTE and region / segment table entries (RSTE).
1990+
* This is also true for swap entries, and their swap type and offset encoding.
1991+
* For hugetlbfs PTE_MARKER support, s390 has internal __swp_type_rste() and
1992+
* __swp_offset_rste() helpers to correctly handle RSTE swap entries.
1993+
*
1994+
* But common swap code does not know about this difference, and only uses
1995+
* __swp_type(), __swp_offset() and __swp_entry() helpers for conversion between
1996+
* arch-dependent and arch-independent representation of swp_entry_t for all
1997+
* pagetable levels. On s390, those helpers only work for PTE swap entries.
1998+
*
1999+
* Therefore, implement __pmd_to_swp_entry() to build a fake PTE swap entry
2000+
* and return the arch-dependent representation of that. Correspondingly,
2001+
* implement __swp_entry_to_pmd() to convert that into a proper PMD swap
2002+
* entry again. With this, the arch-dependent swp_entry_t representation will
2003+
* always look like a PTE swap entry in common code.
2004+
*
2005+
* This is somewhat similar to fake PTEs in hugetlbfs code for s390, but only
2006+
* requires conversion of the swap type and offset, and not all the possible
2007+
* PTE bits.
2008+
*/
2009+
static inline swp_entry_t __pmd_to_swp_entry(pmd_t pmd)
2010+
{
2011+
swp_entry_t arch_entry;
2012+
pte_t pte;
2013+
2014+
arch_entry = __rste_to_swp_entry(pmd_val(pmd));
2015+
pte = mk_swap_pte(__swp_type_rste(arch_entry), __swp_offset_rste(arch_entry));
2016+
return __pte_to_swp_entry(pte);
2017+
}
2018+
2019+
static inline pmd_t __swp_entry_to_pmd(swp_entry_t arch_entry)
2020+
{
2021+
pmd_t pmd;
2022+
2023+
pmd = __pmd(mk_swap_rste(__swp_type(arch_entry), __swp_offset(arch_entry)));
2024+
return pmd;
2025+
}
2026+
19822027
extern int vmem_add_mapping(unsigned long start, unsigned long size);
19832028
extern void vmem_remove_mapping(unsigned long start, unsigned long size);
19842029
extern int __vmem_map_4k_page(unsigned long addr, unsigned long phys, pgprot_t prot, bool alloc);

0 commit comments

Comments
 (0)