diff mbox

[PATCHv9-rebased2,05/37] khugepaged: recheck pmd after mmap_sem re-acquired

Message ID 1466021202-61880-6-git-send-email-kirill.shutemov@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kirill A . Shutemov June 15, 2016, 8:06 p.m. UTC
Vlastimil noted[1] that pmd can be no longer valid after we drop
mmap_sem. We need recheck it once mmap_sem taken again.

[1] http://lkml.kernel.org/r/12918dcd-a695-c6f4-e06f-69141c5f357f@suse.cz

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
---
 mm/huge_memory.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Ebru Akagündüz June 16, 2016, 11:47 a.m. UTC | #1
On Wed, Jun 15, 2016 at 11:06:10PM +0300, Kirill A. Shutemov wrote:
> Vlastimil noted[1] that pmd can be no longer valid after we drop
> mmap_sem. We need recheck it once mmap_sem taken again.
> 
> [1] http://lkml.kernel.org/r/12918dcd-a695-c6f4-e06f-69141c5f357f@suse.cz
> 
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> ---
>  mm/huge_memory.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index d7ccc8558187..0efdad975659 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -2437,6 +2437,9 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm,
>  			/* vma is no longer available, don't continue to swapin */
>  			if (hugepage_vma_revalidate(mm, address))
>  				return false;
> +			/* check if the pmd is still valid */
> +			if (mm_find_pmd(mm, address) != pmd)
> +				return false;
>  		}
Thanks for fixing this.

>  		if (ret & VM_FAULT_ERROR) {
>  			trace_mm_collapse_huge_page_swapin(mm, swapped_in, 0);
> @@ -2522,6 +2525,9 @@ static void collapse_huge_page(struct mm_struct *mm,
>  	result = hugepage_vma_revalidate(mm, address);
>  	if (result)
>  		goto out;
> +	/* check if the pmd is still valid */
> +	if (mm_find_pmd(mm, address) != pmd)
> +		goto out;
>  
However here, I don't know do we need to check pmd.
Because in collapse_huge_page; pmd is newly created,
after taking mmap_sem read:
{

	pmd_t *pmd, _pmd;
        pte_t *pte;
        ...
        down_read(&mm->mmap_sem);
        result = hugepage_vma_revalidate(mm, address);
        ...
        pmd = mm_find_pmd(mm, address);
        ...

Therefore it did not seem like a problem for me.

>  	anon_vma_lock_write(vma->anon_vma);
>  
> -- 
> 2.8.1
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kirill A. Shutemov June 16, 2016, 11:51 a.m. UTC | #2
On Thu, Jun 16, 2016 at 02:47:14PM +0300, Ebru Akagunduz wrote:
> On Wed, Jun 15, 2016 at 11:06:10PM +0300, Kirill A. Shutemov wrote:
> > Vlastimil noted[1] that pmd can be no longer valid after we drop
> > mmap_sem. We need recheck it once mmap_sem taken again.
> > 
> > [1] http://lkml.kernel.org/r/12918dcd-a695-c6f4-e06f-69141c5f357f@suse.cz
> > 
> > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> > ---
> >  mm/huge_memory.c | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> > index d7ccc8558187..0efdad975659 100644
> > --- a/mm/huge_memory.c
> > +++ b/mm/huge_memory.c
> > @@ -2437,6 +2437,9 @@ static bool __collapse_huge_page_swapin(struct mm_struct *mm,
> >  			/* vma is no longer available, don't continue to swapin */
> >  			if (hugepage_vma_revalidate(mm, address))
> >  				return false;
> > +			/* check if the pmd is still valid */
> > +			if (mm_find_pmd(mm, address) != pmd)
> > +				return false;
> >  		}
> Thanks for fixing this.
> 
> >  		if (ret & VM_FAULT_ERROR) {
> >  			trace_mm_collapse_huge_page_swapin(mm, swapped_in, 0);
> > @@ -2522,6 +2525,9 @@ static void collapse_huge_page(struct mm_struct *mm,
> >  	result = hugepage_vma_revalidate(mm, address);
> >  	if (result)
> >  		goto out;
> > +	/* check if the pmd is still valid */
> > +	if (mm_find_pmd(mm, address) != pmd)
> > +		goto out;
> >  
> However here, I don't know do we need to check pmd.
> Because in collapse_huge_page; pmd is newly created,
> after taking mmap_sem read:
> {
> 
> 	pmd_t *pmd, _pmd;
>         pte_t *pte;
>         ...
>         down_read(&mm->mmap_sem);
>         result = hugepage_vma_revalidate(mm, address);
>         ...
>         pmd = mm_find_pmd(mm, address);
>         ...
> 
> Therefore it did not seem like a problem for me.

I guess you're looking on the first hugepage_vma_revalidate() in
collapse_huge_page(). The patch fixes issue after the second one:

	pmd_t *pmd, _pmd;
        pte_t *pte;
        ...
        down_read(&mm->mmap_sem);
        result = hugepage_vma_revalidate(mm, address);
        ...
        pmd = mm_find_pmd(mm, address);
        ...
	up_read(&mm->mmap_sem);
	...
	down_write(&mm->mmap_sem);
	result = hugepage_vma_revalidate(mm, address);
	if (mm_find_pmd(mm, address) != pmd)
		 goto out;
diff mbox

Patch

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index d7ccc8558187..0efdad975659 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2437,6 +2437,9 @@  static bool __collapse_huge_page_swapin(struct mm_struct *mm,
 			/* vma is no longer available, don't continue to swapin */
 			if (hugepage_vma_revalidate(mm, address))
 				return false;
+			/* check if the pmd is still valid */
+			if (mm_find_pmd(mm, address) != pmd)
+				return false;
 		}
 		if (ret & VM_FAULT_ERROR) {
 			trace_mm_collapse_huge_page_swapin(mm, swapped_in, 0);
@@ -2522,6 +2525,9 @@  static void collapse_huge_page(struct mm_struct *mm,
 	result = hugepage_vma_revalidate(mm, address);
 	if (result)
 		goto out;
+	/* check if the pmd is still valid */
+	if (mm_find_pmd(mm, address) != pmd)
+		goto out;
 
 	anon_vma_lock_write(vma->anon_vma);