Message ID | 20190913091849.11151-1-kirill.shutemov@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm, thp: Do not queue fully unmapped pages for deferred split | expand |
On Fri 13-09-19 12:18:49, Kirill A. Shutemov wrote: > Adding fully unmapped pages into deferred split queue is not productive: > these pages are about to be freed or they are pinned and cannot be split > anyway. > > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > --- > mm/rmap.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/mm/rmap.c b/mm/rmap.c > index 003377e24232..45388f1bf317 100644 > --- a/mm/rmap.c > +++ b/mm/rmap.c > @@ -1271,12 +1271,20 @@ static void page_remove_anon_compound_rmap(struct page *page) > if (TestClearPageDoubleMap(page)) { > /* > * Subpages can be mapped with PTEs too. Check how many of > - * themi are still mapped. > + * them are still mapped. > */ > for (i = 0, nr = 0; i < HPAGE_PMD_NR; i++) { > if (atomic_add_negative(-1, &page[i]._mapcount)) > nr++; > } > + > + /* > + * Queue the page for deferred split if at least one small > + * page of the compound page is unmapped, but at least one > + * small page is still mapped. > + */ > + if (nr && nr < HPAGE_PMD_NR) > + deferred_split_huge_page(page); You've set nr to zero in the for loop so this cannot work AFAICS. > } else { > nr = HPAGE_PMD_NR; > } > @@ -1284,10 +1292,8 @@ static void page_remove_anon_compound_rmap(struct page *page) > if (unlikely(PageMlocked(page))) > clear_page_mlock(page); > > - if (nr) { > + if (nr) > __mod_node_page_state(page_pgdat(page), NR_ANON_MAPPED, -nr); > - deferred_split_huge_page(page); > - } > } > > /** > -- > 2.21.0
On 9/16/19 12:36 PM, Michal Hocko wrote: > On Fri 13-09-19 12:18:49, Kirill A. Shutemov wrote: >> Adding fully unmapped pages into deferred split queue is not productive: >> these pages are about to be freed or they are pinned and cannot be split >> anyway. >> >> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> >> --- >> mm/rmap.c | 14 ++++++++++---- >> 1 file changed, 10 insertions(+), 4 deletions(-) >> >> diff --git a/mm/rmap.c b/mm/rmap.c >> index 003377e24232..45388f1bf317 100644 >> --- a/mm/rmap.c >> +++ b/mm/rmap.c >> @@ -1271,12 +1271,20 @@ static void page_remove_anon_compound_rmap(struct page *page) >> if (TestClearPageDoubleMap(page)) { >> /* >> * Subpages can be mapped with PTEs too. Check how many of >> - * themi are still mapped. >> + * them are still mapped. >> */ >> for (i = 0, nr = 0; i < HPAGE_PMD_NR; i++) { >> if (atomic_add_negative(-1, &page[i]._mapcount)) >> nr++; >> } >> + >> + /* >> + * Queue the page for deferred split if at least one small >> + * page of the compound page is unmapped, but at least one >> + * small page is still mapped. >> + */ >> + if (nr && nr < HPAGE_PMD_NR) >> + deferred_split_huge_page(page); > > You've set nr to zero in the for loop so this cannot work AFAICS. The for loop then does nr++ for each subpage that's still mapped? >> } else { >> nr = HPAGE_PMD_NR; >> } >> @@ -1284,10 +1292,8 @@ static void page_remove_anon_compound_rmap(struct page *page) >> if (unlikely(PageMlocked(page))) >> clear_page_mlock(page); >> >> - if (nr) { >> + if (nr) >> __mod_node_page_state(page_pgdat(page), NR_ANON_MAPPED, -nr); >> - deferred_split_huge_page(page); >> - } >> } >> >> /** >> -- >> 2.21.0 >
On Mon 16-09-19 13:11:37, Vlastimil Babka wrote: > On 9/16/19 12:36 PM, Michal Hocko wrote: > > On Fri 13-09-19 12:18:49, Kirill A. Shutemov wrote: > >> Adding fully unmapped pages into deferred split queue is not productive: > >> these pages are about to be freed or they are pinned and cannot be split > >> anyway. > >> > >> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > >> --- > >> mm/rmap.c | 14 ++++++++++---- > >> 1 file changed, 10 insertions(+), 4 deletions(-) > >> > >> diff --git a/mm/rmap.c b/mm/rmap.c > >> index 003377e24232..45388f1bf317 100644 > >> --- a/mm/rmap.c > >> +++ b/mm/rmap.c > >> @@ -1271,12 +1271,20 @@ static void page_remove_anon_compound_rmap(struct page *page) > >> if (TestClearPageDoubleMap(page)) { > >> /* > >> * Subpages can be mapped with PTEs too. Check how many of > >> - * themi are still mapped. > >> + * them are still mapped. > >> */ > >> for (i = 0, nr = 0; i < HPAGE_PMD_NR; i++) { > >> if (atomic_add_negative(-1, &page[i]._mapcount)) > >> nr++; > >> } > >> + > >> + /* > >> + * Queue the page for deferred split if at least one small > >> + * page of the compound page is unmapped, but at least one > >> + * small page is still mapped. > >> + */ > >> + if (nr && nr < HPAGE_PMD_NR) > >> + deferred_split_huge_page(page); > > > > You've set nr to zero in the for loop so this cannot work AFAICS. > > The for loop then does nr++ for each subpage that's still mapped? I am blind obviously. Sorry about the noise. Then the patch looks correct.
On Fri, Sep 13, 2019 at 2:18 AM Kirill A. Shutemov <kirill@shutemov.name> wrote: > > Adding fully unmapped pages into deferred split queue is not productive: > these pages are about to be freed or they are pinned and cannot be split > anyway. This change looks good to me. Reviewed-by: Yang Shi <yang.shi@linux.alibaba.com> > > Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> > --- > mm/rmap.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/mm/rmap.c b/mm/rmap.c > index 003377e24232..45388f1bf317 100644 > --- a/mm/rmap.c > +++ b/mm/rmap.c > @@ -1271,12 +1271,20 @@ static void page_remove_anon_compound_rmap(struct page *page) > if (TestClearPageDoubleMap(page)) { > /* > * Subpages can be mapped with PTEs too. Check how many of > - * themi are still mapped. > + * them are still mapped. > */ > for (i = 0, nr = 0; i < HPAGE_PMD_NR; i++) { > if (atomic_add_negative(-1, &page[i]._mapcount)) > nr++; > } > + > + /* > + * Queue the page for deferred split if at least one small > + * page of the compound page is unmapped, but at least one > + * small page is still mapped. > + */ > + if (nr && nr < HPAGE_PMD_NR) > + deferred_split_huge_page(page); > } else { > nr = HPAGE_PMD_NR; > } > @@ -1284,10 +1292,8 @@ static void page_remove_anon_compound_rmap(struct page *page) > if (unlikely(PageMlocked(page))) > clear_page_mlock(page); > > - if (nr) { > + if (nr) > __mod_node_page_state(page_pgdat(page), NR_ANON_MAPPED, -nr); > - deferred_split_huge_page(page); > - } > } > > /** > -- > 2.21.0 > >
diff --git a/mm/rmap.c b/mm/rmap.c index 003377e24232..45388f1bf317 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1271,12 +1271,20 @@ static void page_remove_anon_compound_rmap(struct page *page) if (TestClearPageDoubleMap(page)) { /* * Subpages can be mapped with PTEs too. Check how many of - * themi are still mapped. + * them are still mapped. */ for (i = 0, nr = 0; i < HPAGE_PMD_NR; i++) { if (atomic_add_negative(-1, &page[i]._mapcount)) nr++; } + + /* + * Queue the page for deferred split if at least one small + * page of the compound page is unmapped, but at least one + * small page is still mapped. + */ + if (nr && nr < HPAGE_PMD_NR) + deferred_split_huge_page(page); } else { nr = HPAGE_PMD_NR; } @@ -1284,10 +1292,8 @@ static void page_remove_anon_compound_rmap(struct page *page) if (unlikely(PageMlocked(page))) clear_page_mlock(page); - if (nr) { + if (nr) __mod_node_page_state(page_pgdat(page), NR_ANON_MAPPED, -nr); - deferred_split_huge_page(page); - } } /**
Adding fully unmapped pages into deferred split queue is not productive: these pages are about to be freed or they are pinned and cannot be split anyway. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- mm/rmap.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)