<div class="__aliyun_email_body_block"><div  style="line-height:1.7;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><div  style="clear:both;">Hi Mike,</div><div  style="clear:both;"><br ></div><div  style="clear:both;">Do you mean the <span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;">similar race is like the following?</span></div><div  style="clear:both;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;"><br ></span></span></div><div  style="clear:both;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;">migration clearing the pte</span></span></div><div  style="clear:both;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;"><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;">  page fault(before we return error, and now we return 0, then try page fault again, right?)</span></span></div><div  style="clear:both;">    migration <span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;">writing a migration </span><span  style="color:#000000;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;text-align:start;text-indent:.0px;text-transform:none;background-color:#ffffff;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;">entry</span></div><div  style="clear:both;"><br ></div><div  style="clear:both;">Thanks,</div><div  style="clear:both;">Xishi Qiu</div><div  style="margin:.0px .0px .0px 30.0px;font-family:Tahoma,Arial,STHeiti,SimSun;font-size:14.0px;color:#000000;"><div  style="clear:both;"><br ></div><div  style="clear:both;"><br ></div>Li Wang discovered that LTP/move_page12 V2 sometimes triggers SIGBUS<br >in the kernel-v5.2.3 testing.  This is caused by a race between hugetlb<br >page migration and page fault.<br ><br >If a hugetlb page can not be allocated to satisfy a page fault, the task<br >is sent SIGBUS.  This is normal hugetlbfs behavior.  A hugetlb fault<br >mutex exists to prevent two tasks from trying to instantiate the same<br >page.  This protects against the situation where there is only one<br >hugetlb page, and both tasks would try to allocate.  Without the mutex,<br >one would fail and SIGBUS even though the other fault would be successful.<br ><br >There is a similar race between hugetlb page migration and fault.<br >Migration code will allocate a page for the target of the migration.<br >It will then unmap the original page from all page tables.  It does<br >this unmap by first clearing the pte and then writing a migration<br >entry.  The page table lock is held for the duration of this clear and<br >write operation.  However, the beginnings of the hugetlb page fault<br >code optimistically checks the pte without taking the page table lock.<br >If clear (as it can be during the migration unmap operation), a hugetlb<br >page allocation is attempted to satisfy the fault.  Note that the page<br >which will eventually satisfy this fault was already allocated by the<br >migration code.  However, the allocation within the fault path could<br >fail which would result in the task incorrectly being sent SIGBUS.<br ><br >Ideally, we could take the hugetlb fault mutex in the migration code<br >when modifying the page tables.  However, locks must be taken in the<br >order of hugetlb fault mutex, page lock, page table lock.  This would<br >require significant rework of the migration code.  Instead, the issue<br >is addressed in the hugetlb fault code.  After failing to allocate a<br >huge page, take the page table lock and check for huge_pte_none before<br >returning an error.  This is the same check that must be made further<br >in the code even if page allocation is successful.<br ><br >Reported-by: Li Wang <liwang@redhat.com><br >Fixes: 290408d4a250 ("hugetlb: hugepage migration core")<br >Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com><br >Tested-by: Li Wang <liwang@redhat.com><br >---<br > mm/hugetlb.c | 19 +++++++++++++++++++<br > 1 file changed, 19 insertions(+)<br ><br >diff --git a/mm/hugetlb.c b/mm/hugetlb.c<br >index ede7e7f5d1ab..6d7296dd11b8 100644<br >--- a/mm/hugetlb.c<br >+++ b/mm/hugetlb.c<br >@@ -3856,6 +3856,25 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm,<br > <br >   page = alloc_huge_page(vma, haddr, 0);<br >   if (IS_ERR(page)) {<br >+   /*<br >+    * Returning error will result in faulting task being<br >+    * sent SIGBUS.  The hugetlb fault mutex prevents two<br >+    * tasks from racing to fault in the same page which<br >+    * could result in false unable to allocate errors.<br >+    * Page migration does not take the fault mutex, but<br >+    * does a clear then write of pte's under page table<br >+    * lock.  Page fault code could race with migration,<br >+    * notice the clear pte and try to allocate a page<br >+    * here.  Before returning error, get ptl and make<br >+    * sure there really is no pte entry.<br >+    */<br >+   ptl = huge_pte_lock(h, mm, ptep);<br >+   if (!huge_pte_none(huge_ptep_get(ptep))) {<br >+    ret = 0;<br >+    spin_unlock(ptl);<br >+    goto out;<br >+   }<br >+   spin_unlock(ptl);<br >    ret = vmf_error(PTR_ERR(page));<br >    goto out;<br >   }<br >-- <br >2.20.1</div><div  style="line-height:20.0px;clear:both;"><br ></div></div></div>