lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 21 Mar 2018 11:14:14 +0100
From:   Daniel Vacek <neelx@...hat.com>
To:     Jia He <hejianet@...il.com>
Cc:     Andrew Morton <akpm@...ux-foundation.org>,
        Michal Hocko <mhocko@...e.com>,
        Catalin Marinas <catalin.marinas@....com>,
        Mel Gorman <mgorman@...e.de>,
        Will Deacon <will.deacon@....com>,
        Mark Rutland <mark.rutland@....com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>,
        "H. Peter Anvin" <hpa@...or.com>,
        Pavel Tatashin <pasha.tatashin@...cle.com>,
        Daniel Jordan <daniel.m.jordan@...cle.com>,
        AKASHI Takahiro <takahiro.akashi@...aro.org>,
        Gioh Kim <gi-oh.kim@...fitbricks.com>,
        Steven Sistare <steven.sistare@...cle.com>,
        Eugeniu Rosca <erosca@...adit-jv.com>,
        Vlastimil Babka <vbabka@...e.cz>,
        open list <linux-kernel@...r.kernel.org>, linux-mm@...ck.org,
        James Morse <james.morse@....com>,
        Ard Biesheuvel <ard.biesheuvel@...aro.org>,
        Steve Capper <steve.capper@....com>, x86@...nel.org,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        Kate Stewart <kstewart@...uxfoundation.org>,
        Philippe Ombredanne <pombredanne@...b.com>,
        Johannes Weiner <hannes@...xchg.org>,
        Kemi Wang <kemi.wang@...el.com>,
        Petr Tesarik <ptesarik@...e.com>,
        YASUAKI ISHIMATSU <yasu.isimatu@...il.com>,
        Andrey Ryabinin <aryabinin@...tuozzo.com>,
        Nikolay Borisov <nborisov@...e.com>,
        Jia He <jia.he@...-semitech.com>
Subject: Re: [PATCH 1/4] mm: page_alloc: reduce unnecessary binary search in memblock_next_valid_pfn()

On Wed, Mar 21, 2018 at 9:09 AM, Jia He <hejianet@...il.com> wrote:
> Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns
> where possible") optimized the loop in memmap_init_zone(). But there is
> still some room for improvement. E.g. if pfn and pfn+1 are in the same
> memblock region, we can simply pfn++ instead of doing the binary search
> in memblock_next_valid_pfn.

There is a revert-mm-page_alloc-skip-over-regions-of-invalid-pfns-where-possible.patch
in -mm reverting b92df1de5d289c0b as it is fundamentally wrong by
design causing system panics on some machines with rare but still
valid mappings. Basically it skips valid pfns which are outside of
usable memory ranges (outside of memblock memory regions).

So I guess if you want to optimize boot up time, you would have to
come up with different solution in memmap_init_zone. Most likely using
mem sections instead of memblock. Sorry.

--nX

> Signed-off-by: Jia He <jia.he@...-semitech.com>
> ---
>  include/linux/memblock.h |  3 +--
>  mm/memblock.c            | 23 +++++++++++++++++++----
>  mm/page_alloc.c          |  3 ++-
>  3 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index b7aa3ff..9471db4 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -203,8 +203,7 @@ void __next_mem_pfn_range(int *idx, int nid, unsigned long *out_start_pfn,
>              i >= 0; __next_mem_pfn_range(&i, nid, p_start, p_end, p_nid))
>  #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
>
> -unsigned long memblock_next_valid_pfn(unsigned long pfn);
> -
> +unsigned long memblock_next_valid_pfn(unsigned long pfn, int *last_idx);
>  /**
>   * for_each_free_mem_range - iterate through free memblock areas
>   * @i: u64 used as loop variable
> diff --git a/mm/memblock.c b/mm/memblock.c
> index c87924d..a9e8da4 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -1133,13 +1133,26 @@ int __init_memblock memblock_set_node(phys_addr_t base, phys_addr_t size,
>  }
>  #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */
>
> -unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn)
> +unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn,
> +                                                       int *last_idx)
>  {
>         struct memblock_type *type = &memblock.memory;
>         unsigned int right = type->cnt;
>         unsigned int mid, left = 0;
> +       unsigned long start_pfn, end_pfn;
>         phys_addr_t addr = PFN_PHYS(++pfn);
>
> +       /* fast path, return pfh+1 if next pfn is in the same region */
> +       if (*last_idx != -1) {
> +               start_pfn = PFN_DOWN(type->regions[*last_idx].base);
> +               end_pfn = PFN_DOWN(type->regions[*last_idx].base +
> +                               type->regions[*last_idx].size);
> +
> +               if (pfn < end_pfn && pfn > start_pfn)
> +                       return pfn;
> +       }
> +
> +       /* slow path, do the binary searching */
>         do {
>                 mid = (right + left) / 2;
>
> @@ -1149,15 +1162,17 @@ unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn)
>                                   type->regions[mid].size))
>                         left = mid + 1;
>                 else {
> -                       /* addr is within the region, so pfn is valid */
> +                       *last_idx = mid;
>                         return pfn;
>                 }
>         } while (left < right);
>
>         if (right == type->cnt)
>                 return -1UL;
> -       else
> -               return PHYS_PFN(type->regions[right].base);
> +
> +       *last_idx = right;
> +
> +       return PHYS_PFN(type->regions[*last_idx].base);
>  }
>
>  static phys_addr_t __init memblock_alloc_range_nid(phys_addr_t size,
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 3899209..f28c62c 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -5456,6 +5456,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
>         unsigned long end_pfn = start_pfn + size;
>         pg_data_t *pgdat = NODE_DATA(nid);
>         unsigned long pfn;
> +       int idx = -1;
>         unsigned long nr_initialised = 0;
>         struct page *page;
>  #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
> @@ -5487,7 +5488,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
>                          * end_pfn), such that we hit a valid pfn (or end_pfn)
>                          * on our next iteration of the loop.
>                          */
> -                       pfn = memblock_next_valid_pfn(pfn) - 1;
> +                       pfn = memblock_next_valid_pfn(pfn, &idx) - 1;
>  #endif
>                         continue;
>                 }
> --
> 2.7.4
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ