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]
Message-ID: <20200613231736.GJ20367@MiWiFi-R3L-srv>
Date:   Sun, 14 Jun 2020 07:17:36 +0800
From:   Baoquan He <bhe@...hat.com>
To:     Jaewon Kim <jaewon31.kim@...il.com>
Cc:     Jaewon Kim <jaewon31.kim@...sung.com>, mgorman@...hsingularity.net,
        minchan@...nel.org, mgorman@...e.de, hannes@...xchg.org,
        Andrew Morton <akpm@...ux-foundation.org>, linux-mm@...ck.org,
        linux-kernel@...r.kernel.org, ytk.lee@...sung.com,
        cmlaika.kim@...sung.com
Subject: Re: [PATCH v2] page_alloc: consider highatomic reserve in
 wmartermark fast

On 06/13/20 at 10:08pm, Jaewon Kim wrote:
...
> > > This is an example of ALLOC_HARDER allocation failure.
> > >
> > > <4>[ 6207.637280]  [3:  Binder:9343_3:22875] Binder:9343_3: page allocation failure: order:0, mode:0x480020(GFP_ATOMIC), nodemask=(null)
> > > <4>[ 6207.637311]  [3:  Binder:9343_3:22875] Call trace:
> > > <4>[ 6207.637346]  [3:  Binder:9343_3:22875] [<ffffff8008f40f8c>] dump_stack+0xb8/0xf0
> > > <4>[ 6207.637356]  [3:  Binder:9343_3:22875] [<ffffff8008223320>] warn_alloc+0xd8/0x12c
> > > <4>[ 6207.637365]  [3:  Binder:9343_3:22875] [<ffffff80082245e4>] __alloc_pages_nodemask+0x120c/0x1250
> > > <4>[ 6207.637374]  [3:  Binder:9343_3:22875] [<ffffff800827f6e8>] new_slab+0x128/0x604
> > > <4>[ 6207.637381]  [3:  Binder:9343_3:22875] [<ffffff800827b0cc>] ___slab_alloc+0x508/0x670
> > > <4>[ 6207.637387]  [3:  Binder:9343_3:22875] [<ffffff800827ba00>] __kmalloc+0x2f8/0x310
> > > <4>[ 6207.637396]  [3:  Binder:9343_3:22875] [<ffffff80084ac3e0>] context_struct_to_string+0x104/0x1cc
> > > <4>[ 6207.637404]  [3:  Binder:9343_3:22875] [<ffffff80084ad8fc>] security_sid_to_context_core+0x74/0x144
> > > <4>[ 6207.637412]  [3:  Binder:9343_3:22875] [<ffffff80084ad880>] security_sid_to_context+0x10/0x18
> > > <4>[ 6207.637421]  [3:  Binder:9343_3:22875] [<ffffff800849bd80>] selinux_secid_to_secctx+0x20/0x28
> > > <4>[ 6207.637430]  [3:  Binder:9343_3:22875] [<ffffff800849109c>] security_secid_to_secctx+0x3c/0x70
> > > <4>[ 6207.637442]  [3:  Binder:9343_3:22875] [<ffffff8008bfe118>] binder_transaction+0xe68/0x454c
> > > <4>[ 6207.637569]  [3:  Binder:9343_3:22875] Mem-Info:
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875] active_anon:102061 inactive_anon:81551 isolated_anon:0
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875]  active_file:59102 inactive_file:68924 isolated_file:64
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875]  unevictable:611 dirty:63 writeback:0 unstable:0
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875]  slab_reclaimable:13324 slab_unreclaimable:44354
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875]  mapped:83015 shmem:4858 pagetables:26316 bounce:0
> > > <4>[ 6207.637595]  [3:  Binder:9343_3:22875]  free:2727 free_pcp:1035 free_cma:178
> > > <4>[ 6207.637616]  [3:  Binder:9343_3:22875] Node 0 active_anon:408244kB inactive_anon:326204kB active_file:236408kB inactive_file:275696kB unevictable:2444kB isolated(anon):0kB isolated(file):256kB mapped:332060kB dirty:252kB writeback:0kB shmem:19432kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no
> > > <4>[ 6207.637627]  [3:  Binder:9343_3:22875] Normal free:10908kB min:6192kB low:44388kB high:47060kB active_anon:409160kB inactive_anon:325924kB active_file:235820kB inactive_file:276628kB unevictable:2444kB writepending:252kB present:3076096kB managed:2673676kB mlocked:2444kB kernel_stack:62512kB pagetables:105264kB bounce:0kB free_pcp:4140kB local_pcp:40kB free_cma:712kB

Checked this mem info, wondering why there's no 'reserved_highatomic'
printing in all these examples.

> > > <4>[ 6207.637632]  [3:  Binder:9343_3:22875] lowmem_reserve[]: 0 0
> > > <4>[ 6207.637637]  [3:  Binder:9343_3:22875] Normal: 505*4kB (H) 357*8kB (H) 201*16kB (H) 65*32kB (H) 1*64kB (H) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 10236kB
> > > <4>[ 6207.637655]  [3:  Binder:9343_3:22875] 138826 total pagecache pages
> > > <4>[ 6207.637663]  [3:  Binder:9343_3:22875] 5460 pages in swap cache
> > > <4>[ 6207.637668]  [3:  Binder:9343_3:22875] Swap cache stats: add 8273090, delete 8267506, find 1004381/4060142
> > >
...
> > >  mm/page_alloc.c | 61 ++++++++++++++++++++++++++++---------------------
> > >  1 file changed, 35 insertions(+), 26 deletions(-)
> > >
> > > diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> > > index 48eb0f1410d4..c2177e056f19 100644
> > > --- a/mm/page_alloc.c
> > > +++ b/mm/page_alloc.c
> > > @@ -3487,6 +3487,29 @@ static noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
> > >  }
> > >  ALLOW_ERROR_INJECTION(should_fail_alloc_page, TRUE);
> > >
> > > +static inline long __zone_watermark_unusable_free(struct zone *z,
> > > +                             unsigned int order, unsigned int alloc_flags)
> > > +{
> > > +     const bool alloc_harder = (alloc_flags & (ALLOC_HARDER|ALLOC_OOM));
> > > +     long unusable_free = (1 << order) - 1;
> > > +
> > > +     /*
> > > +      * If the caller does not have rights to ALLOC_HARDER then subtract
> > > +      * the high-atomic reserves. This will over-estimate the size of the
> > > +      * atomic reserve but it avoids a search.
> > > +      */
> > > +     if (likely(!alloc_harder))
> > > +             unusable_free += z->nr_reserved_highatomic;
> > > +
> > > +#ifdef CONFIG_CMA
> > > +     /* If allocation can't use CMA areas don't use free CMA pages */
> > > +     if (!(alloc_flags & ALLOC_CMA))
> > > +             unusable_free += zone_page_state(z, NR_FREE_CMA_PAGES);
> > > +#endif
> > > +
> > > +     return unusable_free;
> > > +}
> > > +
> > >  /*
> > >   * Return true if free base pages are above 'mark'. For high-order checks it
> > >   * will return true of the order-0 watermark is reached and there is at least
> > > @@ -3502,19 +3525,12 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
> > >       const bool alloc_harder = (alloc_flags & (ALLOC_HARDER|ALLOC_OOM));
> > >
> > >       /* free_pages may go negative - that's OK */
> > > -     free_pages -= (1 << order) - 1;
> > > +     free_pages -= __zone_watermark_unusable_free(z, order, alloc_flags);
> > >
> > >       if (alloc_flags & ALLOC_HIGH)
> > >               min -= min / 2;
> > >
> > > -     /*
> > > -      * If the caller does not have rights to ALLOC_HARDER then subtract
> > > -      * the high-atomic reserves. This will over-estimate the size of the
> > > -      * atomic reserve but it avoids a search.
> > > -      */
> > > -     if (likely(!alloc_harder)) {
> > > -             free_pages -= z->nr_reserved_highatomic;
> > > -     } else {
> > > +     if (unlikely(alloc_harder)) {
> > >               /*
> > >                * OOM victims can try even harder than normal ALLOC_HARDER
> > >                * users on the grounds that it's definitely going to be in
> > > @@ -3527,13 +3543,6 @@ bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
> > >                       min -= min / 4;
> > >       }
> > >
> > > -
> > > -#ifdef CONFIG_CMA
> > > -     /* If allocation can't use CMA areas don't use free CMA pages */
> > > -     if (!(alloc_flags & ALLOC_CMA))
> > > -             free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
> > > -#endif
> > > -
> > >       /*
> > >        * Check watermarks for an order-0 allocation request. If these
> > >        * are not met, then a high-order request also cannot go ahead
> > > @@ -3582,14 +3591,11 @@ static inline bool zone_watermark_fast(struct zone *z, unsigned int order,
> > >                               unsigned long mark, int highest_zoneidx,
> > >                               unsigned int alloc_flags)
> > >  {
> > > -     long free_pages = zone_page_state(z, NR_FREE_PAGES);
> > > -     long cma_pages = 0;
> > > +     long free_pages;
> > > +     long unusable_free;
> > >
> > > -#ifdef CONFIG_CMA
> > > -     /* If allocation can't use CMA areas don't use free CMA pages */
> > > -     if (!(alloc_flags & ALLOC_CMA))
> > > -             cma_pages = zone_page_state(z, NR_FREE_CMA_PAGES);
> > > -#endif
> > > +     free_pages = zone_page_state(z, NR_FREE_PAGES);
> > > +     unusable_free =  __zone_watermark_unusable_free(z, order, alloc_flags);
> > >
> > >       /*
> > >        * Fast check for order-0 only. If this fails then the reserves
> > > @@ -3598,9 +3604,12 @@ static inline bool zone_watermark_fast(struct zone *z, unsigned int order,
> > >        * the caller is !atomic then it'll uselessly search the free
> > >        * list. That corner case is then slower but it is harmless.
> >
> > Do we need remove or adjust the code comment at this place? So Mel have
> > foreseen the corner case, just reclaiming to unreserve the highatomic
> > might be ignored.
> >
> 
> Hello thank you for your comment.
> 
> My previous mail to Vlastimil Babka seems to have html.
> Let me put  again here because I also think the comment should be changed.
> I'd like to hear opinions from the open source community.

Yeah, your replying mail to Vlastimil looks a little messy on format, I
didn't scroll down to check.

> 
> Additionally actually I think we need accurate counting of highatomic
> free after this patch.
> 
> ----------------------------------------------------------------------------------------
> 
> As Mel also agreed with me in v1 mail thread, this highatomic reserved should
> be considered even in watermark fast.
> 
> The comment, I think, may need to be changed. Prior to this patch, non
> highatomic
> allocation may do useless search, but it also can take ALL non highatomic free.
> 
> With this patch, non highatomic allocation will NOT do useless search. Rather,
> it may be required direct reclamation even when there are some non
> high atomic free.
> 
> i.e)
> In following situation, watermark check fails (9MB - 8MB < 4MB) though there are
> enough free (9MB - 4MB > 4MB). If this is really matter, we need to
> count highatomic
> free accurately.

Seems to make sense. We only use zone->nr_reserved_highatomic to account
the reserved highatomic, don't track how much have been used for
highatomic allocation. But not sure if this will happen often, or just a
very rare case, whether taking that into account will impact anything.

> 
> min : 4MB,
> highatomic reserved : 8MB
> Total free : 9MB
>   actual highatomic free : 4MB
>   non highatomic free : 5MB
> 
> > >        */
> > > -     if (!order && (free_pages - cma_pages) >
> > > -                             mark + z->lowmem_reserve[highest_zoneidx])
> > > -             return true;
> > > +     if (!order) {
> > > +             long fast_free = free_pages - unusable_free;
> > > +
> > > +             if (fast_free > mark + z->lowmem_reserve[highest_zoneidx])
> > > +                     return true;
> > > +     }
> > >
> > >       return __zone_watermark_ok(z, order, mark, highest_zoneidx, alloc_flags,
> > >                                       free_pages);
> > > --
> > > 2.17.1
> > >
> > >
> >
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ