Re: [RFC PATCH] mm: dump_page: print total mapcount for compound page

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 28, 2021 at 11:26 AM John Hubbard <jhubbard@xxxxxxxxxx> wrote:
>
> On 5/28/21 10:54 AM, Yang Shi wrote:
> > The total mapcount is a useful information for debugging, but we can't
> > call total_mapcount() directly since it calls some assertions which may
> > be triggered as commit 6dc5ea16c86f ("mm,
> > dump_page: do not crash with bad compound_mapcount()") met.
> >
> > We could implement yet another implementation for dump_page() but
> > it has the limitation when individual mapcount of subpages is corrupted.
> >
> > Actually the total mapcount could be decoded from refcount, pincount and
> > compound mapcount although it may be not very precise due to some
> > transient references.
>
> If the mapcount calculation were in a separate routine, *and* if something
> else in addition to dump_page() used it, then I'd be interested in
> calling it from dump_page().

There is. The total_mapcount() is used by mm code. But as I mentioned
in the commit log and that discussion email, it is not safe to call it
directly in dump_page() path.

>
> But, just adding a calculation glob like this is not a good idea. If
> the reader really needs the calculation, then that person can, as you
> say, work it out from the other information.
>
> Debug and dump routines are actually supposed to remain fairly simple,
> so that they themselves do not end up with bugs, or stale assumptions
> (which this calculation is very much susceptible to). This goes in the
> wrong direction.
>
> So best to just not do this, IMHO.
>
> thanks,
> --
> John Hubbard
> NVIDIA
>
> >
> > Signed-off-by: Yang Shi <shy828301@xxxxxxxxx>
> > ---
> > I think we are on the same page that the total mapcount is useful
> > information and it would be ideal to print this information when dumpping
> > page if possible.  But how to implement it safely seems controversial.
> > Some ideas and potential problems have been discussed by
> > https://lore.kernel.org/linux-mm/alpine.LSU.2.11.2105261733110.16920@eggly.anvils/.
> >
> > So I prepared this patch to show a possible approach to get some
> > feedback.  The same thing could be decoded by the reader of page dump
> > as well by using the same formula used by this patch.  However it sounds
> > more convenient to have kernel do the math.
> >
> >   mm/debug.c | 35 +++++++++++++++++++++++++++++------
> >   1 file changed, 29 insertions(+), 6 deletions(-)
> >
> > diff --git a/mm/debug.c b/mm/debug.c
> > index e73fe0a8ec3d..129efcfcaf79 100644
> > --- a/mm/debug.c
> > +++ b/mm/debug.c
> > @@ -54,8 +54,13 @@ static void __dump_page(struct page *page)
> >        * inaccuracy here due to racing.
> >        */
> >       bool page_cma = is_migrate_cma_page(page);
> > -     int mapcount;
> > +     int mapcount, total_mapcount;
> > +     int nr;
> > +     int refcount;
> > +     int pincount = 0;
> > +     int comp_mapcnt;
> >       char *type = "";
> > +     bool is_slab = PageSlab(head);
> >
> >       if (page < head || (page >= head + MAX_ORDER_NR_PAGES)) {
> >               /*
> > @@ -82,22 +87,40 @@ static void __dump_page(struct page *page)
> >        * page->_mapcount space in struct page is used by sl[aou]b pages to
> >        * encode own info.
> >        */
> > -     mapcount = PageSlab(head) ? 0 : page_mapcount(page);
> > +     mapcount = is_slab ? 0 : page_mapcount(page);
> > +
> > +     refcount = page_ref_count(head);
> >
> >       pr_warn("page:%p refcount:%d mapcount:%d mapping:%p index:%#lx pfn:%#lx\n",
> > -                     page, page_ref_count(head), mapcount, mapping,
> > +                     page, refcount, mapcount, mapping,
> >                       page_to_pgoff(page), page_to_pfn(page));
> >       if (compound) {
> > +             comp_mapcnt = head_compound_mapcount(head);
> >               if (hpage_pincount_available(page)) {
> > +                     pincount = head_compound_pincount(head);
> >                       pr_warn("head:%p order:%u compound_mapcount:%d compound_pincount:%d\n",
> >                                       head, compound_order(head),
> > -                                     head_compound_mapcount(head),
> > -                                     head_compound_pincount(head));
> > +                                     comp_mapcnt, pincount);
> >               } else {
> >                       pr_warn("head:%p order:%u compound_mapcount:%d\n",
> >                                       head, compound_order(head),
> > -                                     head_compound_mapcount(head));
> > +                                     comp_mapcnt);
> > +             }
> > +
> > +             nr = compound_nr(head);
> > +             if (is_slab)
> > +                     total_mapcount = 0;
> > +             else if (PageHuge(head))
> > +                     total_mapcount = comp_mapcnt;
> > +             else {
> > +                     if (mapping) {
> > +                             if (!PageAnon(head))
> > +                                     nr = nr * (comp_mapcnt + 1) - comp_mapcnt;
> > +                     } else
> > +                             nr = 0;
> > +                     total_mapcount = refcount - pincount - nr;
> >               }
> > +             pr_warn("total_mapcount(estimated):%d\n", total_mapcount);
> >       }
> >
> >   #ifdef CONFIG_MEMCG
> >
>




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux