lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 239/254] powerpc/hash64/devmap: Use H_PAGE_THP_HUGE when setting up huge devmap PTE entries
    Date
    From: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>

    commit 36b78402d97a3b9aeab136feb9b00d8647ec2c20 upstream.

    H_PAGE_THP_HUGE is used to differentiate between a THP hugepage and
    hugetlb hugepage entries. The difference is WRT how we handle hash
    fault on these address. THP address enables MPSS in segments. We want
    to manage devmap hugepage entries similar to THP pt entries. Hence use
    H_PAGE_THP_HUGE for devmap huge PTE entries.

    With current code while handling hash PTE fault, we do set is_thp =
    true when finding devmap PTE huge PTE entries.

    Current code also does the below sequence we setting up huge devmap
    entries.

    entry = pmd_mkhuge(pfn_t_pmd(pfn, prot));
    if (pfn_t_devmap(pfn))
    entry = pmd_mkdevmap(entry);

    In that case we would find both H_PAGE_THP_HUGE and PAGE_DEVMAP set
    for huge devmap PTE entries. This results in false positive error like
    below.

    kernel BUG at /home/kvaneesh/src/linux/mm/memory.c:4321!
    Oops: Exception in kernel mode, sig: 5 [#1]
    LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
    Modules linked in:
    CPU: 56 PID: 67996 Comm: t_mmap_dio Not tainted 5.6.0-rc4-59640-g371c804dedbc #128
    ....
    NIP [c00000000044c9e4] __follow_pte_pmd+0x264/0x900
    LR [c0000000005d45f8] dax_writeback_one+0x1a8/0x740
    Call Trace:
    str_spec.74809+0x22ffb4/0x2d116c (unreliable)
    dax_writeback_one+0x1a8/0x740
    dax_writeback_mapping_range+0x26c/0x700
    ext4_dax_writepages+0x150/0x5a0
    do_writepages+0x68/0x180
    __filemap_fdatawrite_range+0x138/0x180
    file_write_and_wait_range+0xa4/0x110
    ext4_sync_file+0x370/0x6e0
    vfs_fsync_range+0x70/0xf0
    sys_msync+0x220/0x2e0
    system_call+0x5c/0x68

    This is because our pmd_trans_huge check doesn't exclude _PAGE_DEVMAP.

    To make this all consistent, update pmd_mkdevmap to set
    H_PAGE_THP_HUGE and pmd_trans_huge check now excludes _PAGE_DEVMAP
    correctly.

    Fixes: ebd31197931d ("powerpc/mm: Add devmap support for ppc64")
    Cc: stable@vger.kernel.org # v4.13+
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20200313094842.351830-1-aneesh.kumar@linux.ibm.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/powerpc/include/asm/book3s/64/hash-4k.h | 6 ++++++
    arch/powerpc/include/asm/book3s/64/hash-64k.h | 8 +++++++-
    arch/powerpc/include/asm/book3s/64/pgtable.h | 4 +++-
    arch/powerpc/include/asm/book3s/64/radix.h | 5 +++++
    4 files changed, 21 insertions(+), 2 deletions(-)

    --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h
    +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h
    @@ -156,6 +156,12 @@ extern pmd_t hash__pmdp_huge_get_and_cle
    extern int hash__has_transparent_hugepage(void);
    #endif

    +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
    +{
    + BUG();
    + return pmd;
    +}
    +
    #endif /* !__ASSEMBLY__ */

    #endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */
    --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h
    +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h
    @@ -246,7 +246,7 @@ static inline void mark_hpte_slot_valid(
    */
    static inline int hash__pmd_trans_huge(pmd_t pmd)
    {
    - return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE)) ==
    + return !!((pmd_val(pmd) & (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP)) ==
    (_PAGE_PTE | H_PAGE_THP_HUGE));
    }

    @@ -272,6 +272,12 @@ extern pmd_t hash__pmdp_huge_get_and_cle
    unsigned long addr, pmd_t *pmdp);
    extern int hash__has_transparent_hugepage(void);
    #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
    +
    +static inline pmd_t hash__pmd_mkdevmap(pmd_t pmd)
    +{
    + return __pmd(pmd_val(pmd) | (_PAGE_PTE | H_PAGE_THP_HUGE | _PAGE_DEVMAP));
    +}
    +
    #endif /* __ASSEMBLY__ */

    #endif /* _ASM_POWERPC_BOOK3S_64_HASH_64K_H */
    --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
    +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
    @@ -1303,7 +1303,9 @@ extern void serialize_against_pte_lookup

    static inline pmd_t pmd_mkdevmap(pmd_t pmd)
    {
    - return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
    + if (radix_enabled())
    + return radix__pmd_mkdevmap(pmd);
    + return hash__pmd_mkdevmap(pmd);
    }

    static inline int pmd_devmap(pmd_t pmd)
    --- a/arch/powerpc/include/asm/book3s/64/radix.h
    +++ b/arch/powerpc/include/asm/book3s/64/radix.h
    @@ -263,6 +263,11 @@ static inline int radix__has_transparent
    }
    #endif

    +static inline pmd_t radix__pmd_mkdevmap(pmd_t pmd)
    +{
    + return __pmd(pmd_val(pmd) | (_PAGE_PTE | _PAGE_DEVMAP));
    +}
    +
    extern int __meminit radix__vmemmap_create_mapping(unsigned long start,
    unsigned long page_size,
    unsigned long phys);

    \
     
     \ /
      Last update: 2020-04-16 16:41    [W:5.657 / U:0.708 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site