> Date: Wed, 17 Jun 2015 09:19:57 +0000
> From: Visa Hankala <[email protected]>
> 
> On Tue, Jun 16, 2015 at 23:57 +0200, Mark Kettenis wrote:
> > You're definitely on to something.  It certainly looks like your diff
> > fixes the bug.  However, if there is no constraint, it would make
> > sense to pick a page from the size tree of the right type.  Not sure
> > if that optimization would really matter though.
> 
> How about the following patch? It adds an opportunistic size tree check
> before the address tree search. If there are no constraints, the
> opportunistically checked entry will be selected directly.
> 
> The updated patch does not seem to have any clear impact on
> performance, at least when there is no heavy memory contention. In my
> cursory tests, kernel build times were effectively the same on an amd64
> with and without the fix. The octeon fared similarly.

Thanks.  Even if there is no performance benefit, reducing
fragmentation helps.

Committed.  Thanks again for figuring this out.

> Index: uvm/uvm_pmemrange.c
> ===================================================================
> RCS file: src/sys/uvm/uvm_pmemrange.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 uvm_pmemrange.c
> --- uvm/uvm_pmemrange.c       13 Nov 2014 00:47:44 -0000      1.44
> +++ uvm/uvm_pmemrange.c       17 Jun 2015 07:12:14 -0000
> @@ -1708,11 +1708,35 @@ uvm_pmr_get1page(psize_t count, int memt
>                               found = TAILQ_NEXT(found, pageq);
>  
>                       if (found == NULL) {
> -                             found = RB_ROOT(&pmr->size[memtype]);
> -                             /* Size tree gives pg[1] instead of pg[0] */
> +                             /*
> +                              * Check if the size tree contains a range
> +                              * that intersects with the boundaries. As the
> +                              * allocation is for any page, try the smallest
> +                              * range so that large ranges are preserved for
> +                              * more constrained cases. Only one entry is
> +                              * checked here, to avoid a brute-force search.
> +                              *
> +                              * Note that a size tree gives pg[1] instead of
> +                              * pg[0].
> +                              */
> +                             found = RB_MIN(uvm_pmr_size,
> +                                 &pmr->size[memtype]);
>                               if (found != NULL) {
>                                       found--;
> -
> +                                     if (!PMR_INTERSECTS_WITH(
> +                                         atop(VM_PAGE_TO_PHYS(found)),
> +                                         atop(VM_PAGE_TO_PHYS(found)) +
> +                                         found->fpgsz, start, end))
> +                                             found = NULL;
> +                             }
> +                     }
> +                     if (found == NULL) {
> +                             /*
> +                              * Try address-guided search to meet the page
> +                              * number constraints.
> +                              */
> +                             found = RB_ROOT(&pmr->addr);
> +                             if (found != NULL) {
>                                       found = uvm_pmr_rootupdate(pmr, found,
>                                           start, end, memtype);
>                               }
> 

Reply via email to