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] [day] [month] [year] [list]
Date:   Mon, 11 Sep 2023 21:59:18 +0200
From:   Vlastimil Babka <vbabka@...e.cz>
To:     Johannes Weiner <hannes@...xchg.org>
Cc:     Mel Gorman <mgorman@...hsingularity.net>,
        Lecopzer Chen <lecopzer.chen@...iatek.com>,
        akpm@...ux-foundation.org, linux-kernel@...r.kernel.org,
        linux-mm@...ck.org, nsaenzju@...hat.com, yj.chiang@...iatek.com,
        Mark-pk Tsai <mark-pk.tsai@...iatek.com>,
        Joe Liu <joe.liu@...iatek.com>
Subject: Re: [PATCH] mm: page_alloc: fix cma pageblock was stolen in rmqueue
 fallback

On 9/11/23 20:11, Johannes Weiner wrote:
> On Mon, Sep 11, 2023 at 06:13:59PM +0200, Vlastimil Babka wrote:
>> On 9/11/23 17:57, Johannes Weiner wrote:
>> > On Tue, Sep 05, 2023 at 10:09:22AM +0100, Mel Gorman wrote:
>> >> mm: page_alloc: Free pages to correct buddy list after PCP lock contention
>> >> 
>> >> Commit 4b23a68f9536 ("mm/page_alloc: protect PCP lists with a spinlock")
>> >> returns pages to the buddy list on PCP lock contention. However, for
>> >> migratetypes that are not MIGRATE_PCPTYPES, the migratetype may have
>> >> been clobbered already for pages that are not being isolated. In
>> >> practice, this means that CMA pages may be returned to the wrong
>> >> buddy list. While this might be harmless in some cases as it is
>> >> MIGRATE_MOVABLE, the pageblock could be reassigned in rmqueue_fallback
>> >> and prevent a future CMA allocation. Lookup the PCP migratetype
>> >> against unconditionally if the PCP lock is contended.
>> >> 
>> >> [lecopzer.chen@...iatek.com: CMA-specific fix]
>> >> Fixes: 4b23a68f9536 ("mm/page_alloc: protect PCP lists with a spinlock")
>> >> Reported-by: Joe Liu <joe.liu@...iatek.com>
>> >> Signed-off-by: Mel Gorman <mgorman@...hsingularity.net>
>> >> ---
>> >>  mm/page_alloc.c | 8 +++++++-
>> >>  1 file changed, 7 insertions(+), 1 deletion(-)
>> >> 
>> >> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
>> >> index 452459836b71..4053c377fee8 100644
>> >> --- a/mm/page_alloc.c
>> >> +++ b/mm/page_alloc.c
>> >> @@ -2428,7 +2428,13 @@ void free_unref_page(struct page *page, unsigned int order)
>> >>  		free_unref_page_commit(zone, pcp, page, migratetype, order);
>> >>  		pcp_spin_unlock(pcp);
>> >>  	} else {
>> >> -		free_one_page(zone, page, pfn, order, migratetype, FPI_NONE);
>> >> +		/*
>> >> +		 * The page migratetype may have been clobbered for types
>> >> +		 * (type >= MIGRATE_PCPTYPES && !is_migrate_isolate) so
>> >> +		 * must be rechecked.
>> >> +		 */
>> >> +		free_one_page(zone, page, pfn, order,
>> >> +			      get_pcppage_migratetype(page), FPI_NONE);
>> >>  	}
>> >>  	pcp_trylock_finish(UP_flags);
>> >>  }
>> >> 
>> > 
>> > I had sent a (similar) fix for this here:
>> > 
>> > https://lore.kernel.org/lkml/20230821183733.106619-4-hannes@cmpxchg.org/
>> > 
>> > The context wasn't CMA, but HIGHATOMIC pages going to the movable
>> > freelist. But the class of bug is the same: the migratetype tweaking
>> > really only applies to the pcplist, not the buddy slowpath; I added a
>> > local pcpmigratetype to make it more clear, and hopefully prevent bugs
>> > of this nature down the line.
>> 
>> Seems to be the cleanest solution to me, indeed.
>> 
>> > I'm just preparing v2 of the above series. Do you want me to break
>> > this change out and send it separately?
>> 
>> Works for me, if you combine the it with the information about what commit
>> that fixes, the CMA implications reported, and Cc stable.
> 
> How about this? Based on v6.6-rc1.
> 
> ---
> 
> From 84e4490095ed3d1f2991e7f0e58e2968e56cc7c0 Mon Sep 17 00:00:00 2001
> From: Johannes Weiner <hannes@...xchg.org>
> Date: Fri, 28 Jul 2023 14:29:41 -0400
> Subject: [PATCH] mm: page_alloc: fix CMA and HIGHATOMIC landing on the wrong
>  buddy list
> 
> Commit 4b23a68f9536 ("mm/page_alloc: protect PCP lists with a
> spinlock") bypasses the pcplist on lock contention and returns the
> page directly to the buddy list of the page's migratetype.
> 
> For pages that don't have their own pcplist, such as CMA and
> HIGHATOMIC, the migratetype is temporarily updated such that the page
> can hitch a ride on the MOVABLE pcplist. Their true type is later
> reassessed when flushing in free_pcppages_bulk(). However, when lock
> contention is detected after the type was already overriden, the
> bypass will then put the page on the wrong buddy list.
> 
> Once on the MOVABLE buddy list, the page becomes eligible for
> fallbacks and even stealing. In the case of HIGHATOMIC, otherwise
> ineligible allocations can dip into the highatomic reserves. In the
> case of CMA, the page can be lost from the CMA region permanently.
> 
> Use a separate pcpmigratetype variable for the pcplist override. Use
> the original migratetype when going directly to the buddy. This fixes
> the bug and should make the intentions more obvious in the code.
> 
> Originally sent here to address the HIGHATOMIC case:
> https://lore.kernel.org/lkml/20230821183733.106619-4-hannes@cmpxchg.org/
> 
> Changelog updated in response to the CMA-specific bug report.
> 
> [mgorman@...hsingularity.net: updated changelog]
> Reported-by: Joe Liu <joe.liu@...iatek.com>
> Fixes: 4b23a68f9536 ("mm/page_alloc: protect PCP lists with a spinlock")
> Cc: stable@...r.kernel.org
> Signed-off-by: Johannes Weiner <hannes@...xchg.org>

Reviewed-by: Vlastimil Babka <vbabka@...e.cz>

> ---
>  mm/page_alloc.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 0c5be12f9336..95546f376302 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -2400,7 +2400,7 @@ void free_unref_page(struct page *page, unsigned int order)
>  	struct per_cpu_pages *pcp;
>  	struct zone *zone;
>  	unsigned long pfn = page_to_pfn(page);
> -	int migratetype;
> +	int migratetype, pcpmigratetype;
>  
>  	if (!free_unref_page_prepare(page, pfn, order))
>  		return;
> @@ -2408,24 +2408,24 @@ void free_unref_page(struct page *page, unsigned int order)
>  	/*
>  	 * We only track unmovable, reclaimable and movable on pcp lists.
>  	 * Place ISOLATE pages on the isolated list because they are being
> -	 * offlined but treat HIGHATOMIC as movable pages so we can get those
> -	 * areas back if necessary. Otherwise, we may have to free
> +	 * offlined but treat HIGHATOMIC and CMA as movable pages so we can
> +	 * get those areas back if necessary. Otherwise, we may have to free
>  	 * excessively into the page allocator
>  	 */
> -	migratetype = get_pcppage_migratetype(page);
> +	migratetype = pcpmigratetype = get_pcppage_migratetype(page);
>  	if (unlikely(migratetype >= MIGRATE_PCPTYPES)) {
>  		if (unlikely(is_migrate_isolate(migratetype))) {
>  			free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE);
>  			return;
>  		}
> -		migratetype = MIGRATE_MOVABLE;
> +		pcpmigratetype = MIGRATE_MOVABLE;
>  	}
>  
>  	zone = page_zone(page);
>  	pcp_trylock_prepare(UP_flags);
>  	pcp = pcp_spin_trylock(zone->per_cpu_pageset);
>  	if (pcp) {
> -		free_unref_page_commit(zone, pcp, page, migratetype, order);
> +		free_unref_page_commit(zone, pcp, page, pcpmigratetype, order);
>  		pcp_spin_unlock(pcp);
>  	} else {
>  		free_one_page(zone, page, pfn, order, migratetype, FPI_NONE);

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ