Message ID | 20250210100948.312130-1-richard120310@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm: pgtable: Unlock pml without branches when !start_pte | expand |
On Mon, 10 Feb 2025 18:09:48 +0800 I Hsin Cheng <richard120310@gmail.com> wrote: > When !start_pte is true, the branch for "start_pte" in "out_ptl" label > section is surely false, and "ptl != pml" must be true since "ptl" is > NULL in this case. > > It means both branches in "out_ptl" are redundant, only one thing to be > done is to unlock "pml", make it directly unlock "pml" and return in > this case. Hopefully the compiler will skip the `if (start_pte)' test. Generally, we try to avoid multiple function return points. We could do --- a/mm/pt_reclaim.c~mm-pgtable-unlock-pml-without-branches-when-start_pte +++ a/mm/pt_reclaim.c @@ -43,7 +43,7 @@ void try_to_free_pte(struct mm_struct *m pml = pmd_lock(mm, pmd); start_pte = pte_offset_map_rw_nolock(mm, pmd, addr, &pmdval, &ptl); if (!start_pte) - goto out_ptl; + goto out_unlock; if (ptl != pml) spin_lock_nested(ptl, SINGLE_DEPTH_NESTING); @@ -67,5 +67,6 @@ out_ptl: if (start_pte) pte_unmap_unlock(start_pte, ptl); if (ptl != pml) +out_unlock: spin_unlock(pml); }
On Mon, Feb 10, 2025 at 04:37:36PM -0800, Andrew Morton wrote: > On Mon, 10 Feb 2025 18:09:48 +0800 I Hsin Cheng <richard120310@gmail.com> wrote: > > > When !start_pte is true, the branch for "start_pte" in "out_ptl" label > > section is surely false, and "ptl != pml" must be true since "ptl" is > > NULL in this case. > > > > It means both branches in "out_ptl" are redundant, only one thing to be > > done is to unlock "pml", make it directly unlock "pml" and return in > > this case. > > Hopefully the compiler will skip the `if (start_pte)' test. > > Generally, we try to avoid multiple function return points. We could do > > --- a/mm/pt_reclaim.c~mm-pgtable-unlock-pml-without-branches-when-start_pte > +++ a/mm/pt_reclaim.c > @@ -43,7 +43,7 @@ void try_to_free_pte(struct mm_struct *m > pml = pmd_lock(mm, pmd); > start_pte = pte_offset_map_rw_nolock(mm, pmd, addr, &pmdval, &ptl); > if (!start_pte) > - goto out_ptl; > + goto out_unlock; > if (ptl != pml) > spin_lock_nested(ptl, SINGLE_DEPTH_NESTING); > > @@ -67,5 +67,6 @@ out_ptl: > if (start_pte) > pte_unmap_unlock(start_pte, ptl); > if (ptl != pml) > +out_unlock: > spin_unlock(pml); > } > _ > > but that's really ugly. Hi Andrew, Thanks for your review! > if (ptl != pml) > +out_unlock: > spin_unlock(pml); > } > _ > > but that's really ugly. I agree. Would you be so nice to suggest some test method for me so I can try to test how much benefit we can get from this? If the case happens frequently enough I think it might be worth it? Best regards, I Hsin Cheng
On Tue, 11 Feb 2025 14:49:47 +0800 I Hsin Cheng <richard120310@gmail.com> wrote: > > if (ptl != pml) > > +out_unlock: > > spin_unlock(pml); > > } > > _ > > > > but that's really ugly. > > I agree. Would you be so nice to suggest some test method for me so I > can try to test how much benefit we can get from this? > > If the case happens frequently enough I think it might be worth it? I expect this error patch is basically never taken - put a printk in there and run some tests?
diff --git a/mm/pt_reclaim.c b/mm/pt_reclaim.c index 7e9455a18aae..f5d5c42a4679 100644 --- a/mm/pt_reclaim.c +++ b/mm/pt_reclaim.c @@ -42,8 +42,10 @@ void try_to_free_pte(struct mm_struct *mm, pmd_t *pmd, unsigned long addr, pml = pmd_lock(mm, pmd); start_pte = pte_offset_map_rw_nolock(mm, pmd, addr, &pmdval, &ptl); - if (!start_pte) - goto out_ptl; + if (!start_pte) { + spin_unlock(pml); + return; + } if (ptl != pml) spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
When !start_pte is true, the branch for "start_pte" in "out_ptl" label section is surely false, and "ptl != pml" must be true since "ptl" is NULL in this case. It means both branches in "out_ptl" are redundant, only one thing to be done is to unlock "pml", make it directly unlock "pml" and return in this case. Signed-off-by: I Hsin Cheng <richard120310@gmail.com> --- mm/pt_reclaim.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)