From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752759AbcBXP6Y (ORCPT ); Wed, 24 Feb 2016 10:58:24 -0500 Received: from mga11.intel.com ([192.55.52.93]:25602 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751240AbcBXP6W (ORCPT ); Wed, 24 Feb 2016 10:58:22 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,494,1449561600"; d="scan'208";a="923014491" From: "Kirill A. Shutemov" To: Andrew Morton , Linus Torvalds Cc: Gerald Schaefer , Christian Borntraeger , Will Deacon , Martin Schwidefsky , Andrea Arcangeli , linux-s390@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Subject: [PATCH] thp: call pmdp_invalidate() with correct virtual address Date: Wed, 24 Feb 2016 18:58:03 +0300 Message-Id: <1456329483-4220-1-git-send-email-kirill.shutemov@linux.intel.com> X-Mailer: git-send-email 2.7.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Sebastian Ott and Gerald Schaefer reported random crashes on s390. It was bisected to my THP refcounting patchset. The problem is that pmdp_invalidated() called with wrong virtual address. It got offset up by HPAGE_PMD_SIZE by loop over ptes. The solution is to introduce new variable to be used in loop and don't touch 'haddr'. Signed-off-by: Kirill A. Shutemov Reported-by: Gerald Schaefer Reported-by Sebastian Ott --- mm/huge_memory.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1c317b85ea7d..e10a4fee88d2 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2836,6 +2836,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, pgtable_t pgtable; pmd_t _pmd; bool young, write, dirty; + unsigned long addr; int i; VM_BUG_ON(haddr & ~HPAGE_PMD_MASK); @@ -2865,7 +2866,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, pgtable = pgtable_trans_huge_withdraw(mm, pmd); pmd_populate(mm, &_pmd, pgtable); - for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) { + for (i = 0, addr = haddr; i < HPAGE_PMD_NR; i++, addr += PAGE_SIZE) { pte_t entry, *pte; /* * Note that NUMA hinting access restrictions are not @@ -2886,9 +2887,9 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, } if (dirty) SetPageDirty(page + i); - pte = pte_offset_map(&_pmd, haddr); + pte = pte_offset_map(&_pmd, addr); BUG_ON(!pte_none(*pte)); - set_pte_at(mm, haddr, pte, entry); + set_pte_at(mm, addr, pte, entry); atomic_inc(&page[i]._mapcount); pte_unmap(pte); } @@ -2938,7 +2939,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, pmd_populate(mm, pmd, pgtable); if (freeze) { - for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) { + for (i = 0; i < HPAGE_PMD_NR; i++) { page_remove_rmap(page + i, false); put_page(page + i); } -- 2.7.0