Linux-kselftest Archive on lore.kernel.org
 help / color / Atom feed
From: Mina Almasry <almasrymina@google.com>
To: Mike Kravetz <mike.kravetz@oracle.com>
Cc: shuah <shuah@kernel.org>, David Rientjes <rientjes@google.com>,
	Shakeel Butt <shakeelb@google.com>,
	Greg Thelen <gthelen@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	open list <linux-kernel@vger.kernel.org>,
	linux-mm@kvack.org, linux-kselftest@vger.kernel.org,
	cgroups@vger.kernel.org
Subject: Re: [PATCH v11 7/9] hugetlb: support file_region coalescing again
Date: Fri, 7 Feb 2020 10:44:34 -0800
Message-ID: <CAHS8izOi6H+BdheSLP0ShW9ugvQzFd3LxdTSNKOBAb2SHLr6YA@mail.gmail.com> (raw)
In-Reply-To: <2541c294-9f61-083b-9a0d-0dfdc3dcac68@oracle.com>

On Thu, Feb 6, 2020 at 4:17 PM Mike Kravetz <mike.kravetz@oracle.com> wrote:
>
> On 2/3/20 3:22 PM, Mina Almasry wrote:
> > An earlier patch in this series disabled file_region coalescing in order
> > to hang the hugetlb_cgroup uncharge info on the file_region entries.
> >
> > This patch re-adds support for coalescing of file_region entries.
> > Essentially everytime we add an entry, we check to see if the
> > hugetlb_cgroup uncharge info is the same as any adjacent entries. If it
> > is, instead of adding an entry we simply extend the appropriate entry.
> >
> > This is an important performance optimization as private mappings add
> > their entries page by page, and we could incur big performance costs for
> > large mappings with lots of file_region entries in their resv_map.
> >
> > Signed-off-by: Mina Almasry <almasrymina@google.com>
> >
> > ---
> >  mm/hugetlb.c | 62 +++++++++++++++++++++++++++++++++++++++++++---------
> >  1 file changed, 52 insertions(+), 10 deletions(-)
> >
> > diff --git a/mm/hugetlb.c b/mm/hugetlb.c
> > index ec0b55ea1506e..058dd9c8269cf 100644
> > --- a/mm/hugetlb.c
> > +++ b/mm/hugetlb.c
> > @@ -272,6 +272,22 @@ static void record_hugetlb_cgroup_uncharge_info(struct hugetlb_cgroup *h_cg,
> >  #endif
> >  }
> >
> > +static bool has_same_uncharge_info(struct file_region *rg,
> > +                                struct hugetlb_cgroup *h_cg,
> > +                                struct hstate *h)
> > +{
> > +#ifdef CONFIG_CGROUP_HUGETLB
> > +     return rg &&
> > +            rg->reservation_counter ==
> > +                    &h_cg->rsvd_hugepage[hstate_index(h)] &&
> > +            rg->pages_per_hpage == pages_per_huge_page(h) &&
> > +            rg->css == &h_cg->css;
> > +
> > +#else
> > +     return true;
> > +#endif
> > +}
> > +
> >  /* Must be called with resv->lock held. Calling this with count_only == true
> >   * will count the number of pages to be added but will not modify the linked
> >   * list. If regions_needed != NULL and count_only == true, then regions_needed
> > @@ -286,7 +302,7 @@ static long add_reservation_in_range(struct resv_map *resv, long f, long t,
> >       long add = 0;
> >       struct list_head *head = &resv->regions;
> >       long last_accounted_offset = f;
> > -     struct file_region *rg = NULL, *trg = NULL, *nrg = NULL;
> > +     struct file_region *rg = NULL, *trg = NULL, *nrg = NULL, *prg = NULL;
> >
> >       if (regions_needed)
> >               *regions_needed = 0;
> > @@ -318,16 +334,34 @@ static long add_reservation_in_range(struct resv_map *resv, long f, long t,
>
> I seem to be missing something.  For context, here is the beginning of that
> loop:
>
>         /* In this loop, we essentially handle an entry for the range
>          * [last_accounted_offset, rg->from), at every iteration, with some
>          * bounds checking.
>          */
>         list_for_each_entry_safe(rg, trg, head, link) {
>                 /* Skip irrelevant regions that start before our range. */
>                 if (rg->from < f) {
>                         /* If this region ends after the last accounted offset,
>                          * then we need to update last_accounted_offset.
>                          */
>                         if (rg->to > last_accounted_offset)
>                                 last_accounted_offset = rg->to;
>                         continue;
>                 }
>
>                 /* When we find a region that starts beyond our range, we've
>                  * finished.
>                  */
>                 if (rg->from > t)
>                         break;
>
> Suppose the resv_map contains one entry [0,2) and we are going to add
> [2,4).  Will we not 'continue' after the first entry and then exit loop
> without setting prg?  So, there is no chance for coalescing?
>

I think you're right; prg needs to be set on all loop exits, including
the continue and break. I'm thinking with that added, the logic should
work, but I need to find a good way to test this. I thought I had good
test coverage but apparently not. I'll fix this in the next iteration.


> --
> Mike Kravetz
>
> >               if (rg->from > last_accounted_offset) {
> >                       add += rg->from - last_accounted_offset;
> >                       if (!count_only) {
> > -                             nrg = get_file_region_entry_from_cache(
> > -                                     resv, last_accounted_offset, rg->from);
> > -                             record_hugetlb_cgroup_uncharge_info(h_cg, nrg,
> > -                                                                 h);
> > -                             list_add(&nrg->link, rg->link.prev);
> > +                             /* Check if the last region can be extended. */
> > +                             if (prg && prg->to == last_accounted_offset &&
> > +                                 has_same_uncharge_info(prg, h_cg, h)) {
> > +                                     prg->to = rg->from;
> > +                             /* Check if the next region can be extended. */
> > +                             } else if (has_same_uncharge_info(rg, h_cg,
> > +                                                               h)) {
> > +                                     rg->from = last_accounted_offset;
> > +                             /* If neither of the regions can be extended,
> > +                              * add a region.
> > +                              */
> > +                             } else {
> > +                                     nrg = get_file_region_entry_from_cache(
> > +                                             resv, last_accounted_offset,
> > +                                             rg->from);
> > +                                     record_hugetlb_cgroup_uncharge_info(
> > +                                             h_cg, nrg, h);
> > +                                     list_add(&nrg->link, rg->link.prev);
> > +                             }
> >                       } else if (regions_needed)
> >                               *regions_needed += 1;
> >               }
> >
> >               last_accounted_offset = rg->to;
> > +             /* Record rg as the 'previous file region' incase we need it
> > +              * for the next iteration.
> > +              */
> > +             prg = rg;
> >       }
> >
> >       /* Handle the case where our range extends beyond
> > @@ -336,10 +370,18 @@ static long add_reservation_in_range(struct resv_map *resv, long f, long t,
> >       if (last_accounted_offset < t) {
> >               add += t - last_accounted_offset;
> >               if (!count_only) {
> > -                     nrg = get_file_region_entry_from_cache(
> > -                             resv, last_accounted_offset, t);
> > -                     record_hugetlb_cgroup_uncharge_info(h_cg, nrg, h);
> > -                     list_add(&nrg->link, rg->link.prev);
> > +                     /* Check if the last region can be extended. */
> > +                     if (prg && prg->to == last_accounted_offset &&
> > +                         has_same_uncharge_info(prg, h_cg, h)) {
> > +                             prg->to = last_accounted_offset;
> > +                     } else {
> > +                             /* If not, just create a new region. */
> > +                             nrg = get_file_region_entry_from_cache(
> > +                                     resv, last_accounted_offset, t);
> > +                             record_hugetlb_cgroup_uncharge_info(h_cg, nrg,
> > +                                                                 h);
> > +                             list_add(&nrg->link, rg->link.prev);
> > +                     }
> >               } else if (regions_needed)
> >                       *regions_needed += 1;
> >       }
> > --
> > 2.25.0.341.g760bfbb309-goog
> >

  reply index

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-03 23:22 [PATCH v11 1/9] hugetlb_cgroup: Add hugetlb_cgroup reservation counter Mina Almasry
2020-02-03 23:22 ` [PATCH v11 2/9] hugetlb_cgroup: add interface for charge/uncharge hugetlb reservations Mina Almasry
2020-02-05 22:08   ` Mike Kravetz
2020-02-06 18:16     ` Mina Almasry
2020-02-03 23:22 ` [PATCH v11 3/9] hugetlb_cgroup: add reservation accounting for private mappings Mina Almasry
2020-02-05 23:26   ` Mike Kravetz
2020-02-03 23:22 ` [PATCH v11 4/9] hugetlb: disable region_add file_region coalescing Mina Almasry
2020-02-05 23:57   ` Mike Kravetz
2020-02-06  1:43     ` Mina Almasry
2020-02-06  2:12       ` Mike Kravetz
2020-02-03 23:22 ` [PATCH v11 5/9] hugetlb_cgroup: add accounting for shared mappings Mina Almasry
2020-02-06 19:33   ` Mike Kravetz
2020-02-06 20:09     ` Mina Almasry
2020-02-03 23:22 ` [PATCH v11 6/9] hugetlb_cgroup: support noreserve mappings Mina Almasry
2020-02-06 22:31   ` Mike Kravetz
2020-02-07 18:16     ` Mike Kravetz
2020-02-11 21:35     ` Mina Almasry
2020-02-11 21:51       ` Mike Kravetz
2020-02-03 23:22 ` [PATCH v11 7/9] hugetlb: support file_region coalescing again Mina Almasry
2020-02-07  0:17   ` Mike Kravetz
2020-02-07 18:44     ` Mina Almasry [this message]
2020-02-03 23:22 ` [PATCH v11 8/9] hugetlb_cgroup: Add hugetlb_cgroup reservation tests Mina Almasry
2020-02-04 16:26   ` Sandipan Das
2020-02-04 20:36     ` Mina Almasry
2020-02-04 22:33       ` Mina Almasry
2020-02-05 12:42         ` Sandipan Das
2020-02-05 18:03           ` Mina Almasry
2020-02-03 23:22 ` [PATCH v11 9/9] hugetlb_cgroup: Add hugetlb_cgroup reservation docs Mina Almasry
2020-02-05 19:36 ` [PATCH v11 1/9] hugetlb_cgroup: Add hugetlb_cgroup reservation counter Mike Kravetz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAHS8izOi6H+BdheSLP0ShW9ugvQzFd3LxdTSNKOBAb2SHLr6YA@mail.gmail.com \
    --to=almasrymina@google.com \
    --cc=akpm@linux-foundation.org \
    --cc=cgroups@vger.kernel.org \
    --cc=gthelen@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mike.kravetz@oracle.com \
    --cc=rientjes@google.com \
    --cc=shakeelb@google.com \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-kselftest Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-kselftest/0 linux-kselftest/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-kselftest linux-kselftest/ https://lore.kernel.org/linux-kselftest \
		linux-kselftest@vger.kernel.org
	public-inbox-index linux-kselftest

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kselftest


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git