Message ID | 20230209101144.496144-1-yajun.deng@linux.dev |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp251792wrn; Thu, 9 Feb 2023 02:23:22 -0800 (PST) X-Google-Smtp-Source: AK7set/sfjH9wzuwOKc0vBzaiIjhC1jOl9F8HxSDb3hAKs6WFbbXSRd99U0I9uyUhLKAFXoqb8Fv X-Received: by 2002:a05:6a20:8401:b0:c0:afba:8b78 with SMTP id c1-20020a056a20840100b000c0afba8b78mr13557524pzd.45.1675938201869; Thu, 09 Feb 2023 02:23:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675938201; cv=none; d=google.com; s=arc-20160816; b=QF7vWKtvoNpWc8deCS9txuh7pUwYU8lMsq2XWx1m7817Fp0+rttWbGLb4fYiqvd8o6 uMYuieUpZsrPJv4eLQXyTK1YxdU+TNdeOupggt1H0F6FZEVimOJm2wzTtiKUFp/Fjm1R vzU+/ngLomUiZQF7o/tCfnCg4/O2B3a/i3GSA6Gq5SJqsrlt7slOyCfkhbwyM85bimgy +DWl5cpbq/42PL9QnhAeV5a4msT3LAT34hnJlhRIRtqW8Ru5/VzwaFRyE1/UOjigRt7O xra1JCRlkQKRo1VcMRpQU560lCGXPy9J9u4V5oUbPUZU2Pq/Zui1/JFY92Wau8VFwwRF dltg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=acc/K+18agrKkErMDlxGWmadF0URH1WEryhRG2AiOO0=; b=ZmoniAK+ZBpfNveunRcnh3rGYw1mQXBHnKGYP7XQcLmynsv5XBpo6mwb2K26PPLQj7 B/OphFt9LfMgTfatfTWV4lF8HkgvU4/2mzhtCCkup0/or1buzPGZTgttjwS+SL6XZyz8 zvuMfxxdR19ZGtvj0b6yJQfvWnFPNOyeHz5BF5RQL2pA7WWzVLHRnu0P/l1kYR0JAZSf pvrHQ4f493WzQlmZg56HYHCS3c49ijLRPvprkK53M+kLPvyv2qZDljvAcOED0ygliMXG jdVA+UzcAPSTMsNj0Qp5D72kvtB0Ry+nfLp5wmxC8qfsOOh0juOBX3LA96y8ZHB31NNr xF8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=bCrZpQ6G; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s5-20020a63b405000000b0047856c2a3dbsi1729722pgf.257.2023.02.09.02.23.09; Thu, 09 Feb 2023 02:23:21 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=bCrZpQ6G; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229863AbjBIKMP (ORCPT <rfc822;ybw1215001957@gmail.com> + 99 others); Thu, 9 Feb 2023 05:12:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40874 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229984AbjBIKML (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 9 Feb 2023 05:12:11 -0500 Received: from out-99.mta1.migadu.com (out-99.mta1.migadu.com [95.215.58.99]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FD9FCDCB for <linux-kernel@vger.kernel.org>; Thu, 9 Feb 2023 02:12:04 -0800 (PST) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1675937521; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=acc/K+18agrKkErMDlxGWmadF0URH1WEryhRG2AiOO0=; b=bCrZpQ6GGjG0vYTus6GLvux5o0qoWwOLfzRuP9WjEQEbWFy2yTDQn52GHf7tn+h7PsM7yC dFHuQKkjLbFgUYl5pEekrFspst31lhqSSKUStdC/LzDt9AN43tyFKDQ8AI3OdQVetbj89B dZVV0wvShWg9mU8EMKnr/qzBEjeRxHw= From: Yajun Deng <yajun.deng@linux.dev> To: akpm@linux-foundation.org Cc: ziy@nvidia.com, mgorman@techsingularity.net, david@redhat.com, vbabka@suse.cz, rppt@linux.ibm.com, osalvador@suse.de, rppt@kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Yajun Deng <yajun.deng@linux.dev> Subject: [PATCH v2] mm/page_alloc: optimize find_suitable_fallback() and fallbacks array Date: Thu, 9 Feb 2023 18:11:44 +0800 Message-Id: <20230209101144.496144-1-yajun.deng@linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1757348575739843200?= X-GMAIL-MSGID: =?utf-8?q?1757348575739843200?= |
Series |
[v2] mm/page_alloc: optimize find_suitable_fallback() and fallbacks array
|
|
Commit Message
Yajun Deng
Feb. 9, 2023, 10:11 a.m. UTC
There is no need to execute the next loop if it not return in the first loop. So add a break at the end of the loop. At the same time, add !migratetype_is_mergeable() before the loop and reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in fallbacks array. Signed-off-by: Yajun Deng <yajun.deng@linux.dev> Acked-by: Vlastimil Babka <vbabka@suse.cz> --- include/linux/mmzone.h | 2 +- mm/page_alloc.c | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-)
Comments
On 9 Feb 2023, at 5:11, Yajun Deng wrote: > There is no need to execute the next loop if it not return in the first > loop. So add a break at the end of the loop. Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? > > At the same time, add !migratetype_is_mergeable() before the loop and > reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in > fallbacks array. You sent a patch: https://lore.kernel.org/all/20230203100132.1627787-1-yajun.deng@linux.dev/T/#u, why not squash this one into that? Why do we need two separate small patches working on the same code? Thanks. > > Signed-off-by: Yajun Deng <yajun.deng@linux.dev> > Acked-by: Vlastimil Babka <vbabka@suse.cz> > --- > include/linux/mmzone.h | 2 +- > mm/page_alloc.c | 11 +++++------ > 2 files changed, 6 insertions(+), 7 deletions(-) > > diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h > index ab94985ee7d9..0a817b8c7fb2 100644 > --- a/include/linux/mmzone.h > +++ b/include/linux/mmzone.h > @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) > * Check whether a migratetype can be merged with another migratetype. > * > * It is only mergeable when it can fall back to other migratetypes for > - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. > + * allocation. See fallbacks[][] array in page_alloc.c. > */ > static inline bool migratetype_is_mergeable(int mt) > { > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 1113483fa6c5..536e8d838fb5 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, > * > * The other migratetypes do not have fallbacks. > */ > -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { > +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { > [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, > [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, > [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, > @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, > int i; > int fallback_mt; > > - if (area->nr_free == 0) > + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) > return -1; > > *can_steal = false; > @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, > if (can_steal_fallback(order, migratetype)) > *can_steal = true; > > - if (!only_stealable) > - return fallback_mt; > - > - if (*can_steal) > + if (!only_stealable || *can_steal) > return fallback_mt; > + else > + break; > } > > return -1; > -- > 2.25.1 -- Best Regards, Yan, Zi
February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: > On 9 Feb 2023, at 5:11, Yajun Deng wrote: > >> There is no need to execute the next loop if it not return in the first >> loop. So add a break at the end of the loop. > > Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back > to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? > And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? > The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' variables. Even if it execute the next loop, it can't change the result. So the loop can be broken if the first loop can't return. >> At the same time, add !migratetype_is_mergeable() before the loop and >> reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in >> fallbacks array. > > You sent a patch: https://lore.kernel.org/all/20230203100132.1627787-1-yajun.deng@linux.dev/T/#u, > why not squash this one into that? Why do > we need two separate small patches working on the same code? > Yes, this is better, but I overlooked this one when I sent the first patch. It is already merged. As Vlastimil Babka said, reduce the first index from MIGRATE_TYPES to MIGRATE_PCPTYPES may be cause out of bounds access of the shrinked fallbacks array If we don't judge the range of migratetype. But this doesn't happen with the second index. > Thanks. > >> Signed-off-by: Yajun Deng <yajun.deng@linux.dev> >> Acked-by: Vlastimil Babka <vbabka@suse.cz> >> --- >> include/linux/mmzone.h | 2 +- >> mm/page_alloc.c | 11 +++++------ >> 2 files changed, 6 insertions(+), 7 deletions(-) >> >> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h >> index ab94985ee7d9..0a817b8c7fb2 100644 >> --- a/include/linux/mmzone.h >> +++ b/include/linux/mmzone.h >> @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) >> * Check whether a migratetype can be merged with another migratetype. >> * >> * It is only mergeable when it can fall back to other migratetypes for >> - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. >> + * allocation. See fallbacks[][] array in page_alloc.c. >> */ >> static inline bool migratetype_is_mergeable(int mt) >> { >> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >> index 1113483fa6c5..536e8d838fb5 100644 >> --- a/mm/page_alloc.c >> +++ b/mm/page_alloc.c >> @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, >> * >> * The other migratetypes do not have fallbacks. >> */ >> -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { >> +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { >> [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, >> [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, >> [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, >> @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >> int i; >> int fallback_mt; >> >> - if (area->nr_free == 0) >> + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) >> return -1; >> >> *can_steal = false; >> @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >> if (can_steal_fallback(order, migratetype)) >> *can_steal = true; >> >> - if (!only_stealable) >> - return fallback_mt; >> - >> - if (*can_steal) >> + if (!only_stealable || *can_steal) >> return fallback_mt; >> + else >> + break; >> } >> >> return -1; >> -- >> 2.25.1 > > -- > Best Regards, > Yan, Zi
On 9 Feb 2023, at 20:57, Yajun Deng wrote: > February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: > >> On 9 Feb 2023, at 5:11, Yajun Deng wrote: >> >>> There is no need to execute the next loop if it not return in the first >>> loop. So add a break at the end of the loop. >> >> Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back >> to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? >> And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? >> > > The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' > variables. Even if it execute the next loop, it can't change the result. So the loop > can be broken if the first loop can't return. OK. Got it. Would the code below look better? for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { fallback_mt = fallbacks[migratetype][i]; if (free_area_empty(area, fallback_mt)) continue; } if (can_steal_fallback(order, migratetype)) *can_steal = true; if (!only_stealable || *can_steal) return fallback_mt; return -1; > >>> At the same time, add !migratetype_is_mergeable() before the loop and >>> reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in >>> fallbacks array. >> >> You sent a patch: https://lore.kernel.org/all/20230203100132.1627787-1-yajun.deng@linux.dev/T/#u, >> why not squash this one into that? Why do >> we need two separate small patches working on the same code? >> > > Yes, this is better, but I overlooked this one when I sent the first patch. It is already merged. > > As Vlastimil Babka said, reduce the first index from MIGRATE_TYPES to MIGRATE_PCPTYPES may be > cause out of bounds access of the shrinked fallbacks array If we don't judge the range of > migratetype. But this doesn't happen with the second index. > >> Thanks. >> >>> Signed-off-by: Yajun Deng <yajun.deng@linux.dev> >>> Acked-by: Vlastimil Babka <vbabka@suse.cz> >>> --- >>> include/linux/mmzone.h | 2 +- >>> mm/page_alloc.c | 11 +++++------ >>> 2 files changed, 6 insertions(+), 7 deletions(-) >>> >>> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h >>> index ab94985ee7d9..0a817b8c7fb2 100644 >>> --- a/include/linux/mmzone.h >>> +++ b/include/linux/mmzone.h >>> @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) >>> * Check whether a migratetype can be merged with another migratetype. >>> * >>> * It is only mergeable when it can fall back to other migratetypes for >>> - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. >>> + * allocation. See fallbacks[][] array in page_alloc.c. >>> */ >>> static inline bool migratetype_is_mergeable(int mt) >>> { >>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >>> index 1113483fa6c5..536e8d838fb5 100644 >>> --- a/mm/page_alloc.c >>> +++ b/mm/page_alloc.c >>> @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, >>> * >>> * The other migratetypes do not have fallbacks. >>> */ >>> -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { >>> +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { >>> [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, >>> [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, >>> [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, >>> @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >>> int i; >>> int fallback_mt; >>> >>> - if (area->nr_free == 0) >>> + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) >>> return -1; >>> >>> *can_steal = false; >>> @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >>> if (can_steal_fallback(order, migratetype)) >>> *can_steal = true; >>> >>> - if (!only_stealable) >>> - return fallback_mt; >>> - >>> - if (*can_steal) >>> + if (!only_stealable || *can_steal) >>> return fallback_mt; >>> + else >>> + break; >>> } >>> >>> return -1; >>> -- >>> 2.25.1 >> >> -- >> Best Regards, >> Yan, Zi -- Best Regards, Yan, Zi
February 10, 2023 10:14 AM, "Zi Yan" <ziy@nvidia.com> wrote: > On 9 Feb 2023, at 20:57, Yajun Deng wrote: > >> February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: >> >>> On 9 Feb 2023, at 5:11, Yajun Deng wrote: >> >> There is no need to execute the next loop if it not return in the first >> loop. So add a break at the end of the loop. >>> Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back >>> to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? >>> And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? >> >> The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' >> variables. Even if it execute the next loop, it can't change the result. So the loop >> can be broken if the first loop can't return. > > OK. Got it. Would the code below look better? > > for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { > fallback_mt = fallbacks[migratetype][i]; > if (free_area_empty(area, fallback_mt)) > continue; > } > > if (can_steal_fallback(order, migratetype)) > *can_steal = true; > > if (!only_stealable || *can_steal) > return fallback_mt; > > return -1; > Yes, I'll submit a v3 patch. Thanks. >> At the same time, add !migratetype_is_mergeable() before the loop and >> reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in >> fallbacks array. >>> You sent a patch: https://lore.kernel.org/all/20230203100132.1627787-1-yajun.deng@linux.dev/T/#u, >>> why not squash this one into that? Why do >>> we need two separate small patches working on the same code? >> >> Yes, this is better, but I overlooked this one when I sent the first patch. It is already merged. >> >> As Vlastimil Babka said, reduce the first index from MIGRATE_TYPES to MIGRATE_PCPTYPES may be >> cause out of bounds access of the shrinked fallbacks array If we don't judge the range of >> migratetype. But this doesn't happen with the second index. >> >>> Thanks. >> >> Signed-off-by: Yajun Deng <yajun.deng@linux.dev> >> Acked-by: Vlastimil Babka <vbabka@suse.cz> >> --- >> include/linux/mmzone.h | 2 +- >> mm/page_alloc.c | 11 +++++------ >> 2 files changed, 6 insertions(+), 7 deletions(-) >> >> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h >> index ab94985ee7d9..0a817b8c7fb2 100644 >> --- a/include/linux/mmzone.h >> +++ b/include/linux/mmzone.h >> @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) >> * Check whether a migratetype can be merged with another migratetype. >> * >> * It is only mergeable when it can fall back to other migratetypes for >> - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. >> + * allocation. See fallbacks[][] array in page_alloc.c. >> */ >> static inline bool migratetype_is_mergeable(int mt) >> { >> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >> index 1113483fa6c5..536e8d838fb5 100644 >> --- a/mm/page_alloc.c >> +++ b/mm/page_alloc.c >> @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, >> * >> * The other migratetypes do not have fallbacks. >> */ >> -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { >> +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { >> [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, >> [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, >> [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, >> @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >> int i; >> int fallback_mt; >> >> - if (area->nr_free == 0) >> + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) >> return -1; >> >> *can_steal = false; >> @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >> if (can_steal_fallback(order, migratetype)) >> *can_steal = true; >> >> - if (!only_stealable) >> - return fallback_mt; >> - >> - if (*can_steal) >> + if (!only_stealable || *can_steal) >> return fallback_mt; >> + else >> + break; >> } >> >> return -1; >> -- >> 2.25.1 >>> -- >>> Best Regards, >>> Yan, Zi > > -- > Best Regards, > Yan, Zi
February 10, 2023 10:33 AM, "Yajun Deng" <yajun.deng@linux.dev> wrote: > February 10, 2023 10:14 AM, "Zi Yan" <ziy@nvidia.com> wrote: > >> On 9 Feb 2023, at 20:57, Yajun Deng wrote: >> >>> February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: >> >> On 9 Feb 2023, at 5:11, Yajun Deng wrote: >>> There is no need to execute the next loop if it not return in the first >>> loop. So add a break at the end of the loop. >> >> Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back >> to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? >> And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? >>> The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' >>> variables. Even if it execute the next loop, it can't change the result. So the loop >>> can be broken if the first loop can't return. >> >> OK. Got it. Would the code below look better? >> >> for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { >> fallback_mt = fallbacks[migratetype][i]; >> if (free_area_empty(area, fallback_mt)) >> continue; >> } >> >> if (can_steal_fallback(order, migratetype)) >> *can_steal = true; >> >> if (!only_stealable || *can_steal) >> return fallback_mt; >> >> return -1; > > Yes, I'll submit a v3 patch. > Thanks. > I found a logical error in your code. It should be like this: for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { fallback_mt = fallbacks[migratetype][i]; if (!free_area_empty(area, fallback_mt)) break; } if (can_steal_fallback(order, migratetype)) *can_steal = true; if (!only_stealable || *can_steal) return fallback_mt; return -1; This code will modify the logic to the opposite. So can anyone tell me if I should use this code or the v2 patch? >>> At the same time, add !migratetype_is_mergeable() before the loop and >>> reduce the first index size from MIGRATE_TYPES to MIGRATE_PCPTYPES in >>> fallbacks array. >> >> You sent a patch: https://lore.kernel.org/all/20230203100132.1627787-1-yajun.deng@linux.dev/T/#u, >> why not squash this one into that? Why do >> we need two separate small patches working on the same code? >>> Yes, this is better, but I overlooked this one when I sent the first patch. It is already merged. >>> >>> As Vlastimil Babka said, reduce the first index from MIGRATE_TYPES to MIGRATE_PCPTYPES may be >>> cause out of bounds access of the shrinked fallbacks array If we don't judge the range of >>> migratetype. But this doesn't happen with the second index. >> >> Thanks. >>> Signed-off-by: Yajun Deng <yajun.deng@linux.dev> >>> Acked-by: Vlastimil Babka <vbabka@suse.cz> >>> --- >>> include/linux/mmzone.h | 2 +- >>> mm/page_alloc.c | 11 +++++------ >>> 2 files changed, 6 insertions(+), 7 deletions(-) >>> >>> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h >>> index ab94985ee7d9..0a817b8c7fb2 100644 >>> --- a/include/linux/mmzone.h >>> +++ b/include/linux/mmzone.h >>> @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) >>> * Check whether a migratetype can be merged with another migratetype. >>> * >>> * It is only mergeable when it can fall back to other migratetypes for >>> - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. >>> + * allocation. See fallbacks[][] array in page_alloc.c. >>> */ >>> static inline bool migratetype_is_mergeable(int mt) >>> { >>> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >>> index 1113483fa6c5..536e8d838fb5 100644 >>> --- a/mm/page_alloc.c >>> +++ b/mm/page_alloc.c >>> @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, >>> * >>> * The other migratetypes do not have fallbacks. >>> */ >>> -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { >>> +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { >>> [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, >>> [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, >>> [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, >>> @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >>> int i; >>> int fallback_mt; >>> >>> - if (area->nr_free == 0) >>> + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) >>> return -1; >>> >>> *can_steal = false; >>> @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, >>> if (can_steal_fallback(order, migratetype)) >>> *can_steal = true; >>> >>> - if (!only_stealable) >>> - return fallback_mt; >>> - >>> - if (*can_steal) >>> + if (!only_stealable || *can_steal) >>> return fallback_mt; >>> + else >>> + break; >>> } >>> >>> return -1; >>> -- >>> 2.25.1 >> >> -- >> Best Regards, >> Yan, Zi >> >> -- >> Best Regards, >> Yan, Zi
On 2/10/23 03:51, Yajun Deng wrote: > February 10, 2023 10:33 AM, "Yajun Deng" <yajun.deng@linux.dev> wrote: > >> February 10, 2023 10:14 AM, "Zi Yan" <ziy@nvidia.com> wrote: >> >>> On 9 Feb 2023, at 20:57, Yajun Deng wrote: >>> >>>> February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: >>> >>> On 9 Feb 2023, at 5:11, Yajun Deng wrote: >>>> There is no need to execute the next loop if it not return in the first >>>> loop. So add a break at the end of the loop. >>> >>> Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back >>> to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? >>> And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? >>>> The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' >>>> variables. Even if it execute the next loop, it can't change the result. So the loop >>>> can be broken if the first loop can't return. >>> >>> OK. Got it. Would the code below look better? >>> >>> for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { >>> fallback_mt = fallbacks[migratetype][i]; >>> if (free_area_empty(area, fallback_mt)) >>> continue; >>> } >>> >>> if (can_steal_fallback(order, migratetype)) >>> *can_steal = true; >>> >>> if (!only_stealable || *can_steal) >>> return fallback_mt; >>> >>> return -1; >> >> Yes, I'll submit a v3 patch. >> Thanks. >> > > I found a logical error in your code. It should be like this: > > for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { > fallback_mt = fallbacks[migratetype][i]; > if (!free_area_empty(area, fallback_mt)) > break; > } > > if (can_steal_fallback(order, migratetype)) > *can_steal = true; > > if (!only_stealable || *can_steal) > return fallback_mt; > > return -1; > > This code will modify the logic to the opposite. It's still wrong, IMHO. If all fallbacks have free_area_empty(), it will return the last one and not -1. Also will set *can_steal in such case. > So can anyone tell me if I should use this code or the v2 patch? Once that bugs are fixed, the result will probably not look much better than v2, so I don't mind keeping v2.
February 10, 2023 3:58 PM, "Vlastimil Babka" <vbabka@suse.cz> wrote: > On 2/10/23 03:51, Yajun Deng wrote: > >> February 10, 2023 10:33 AM, "Yajun Deng" <yajun.deng@linux.dev> wrote: >> >>> February 10, 2023 10:14 AM, "Zi Yan" <ziy@nvidia.com> wrote: >> >> On 9 Feb 2023, at 20:57, Yajun Deng wrote: >> >> February 9, 2023 11:50 PM, "Zi Yan" <ziy@nvidia.com> wrote: >> >> On 9 Feb 2023, at 5:11, Yajun Deng wrote: >> There is no need to execute the next loop if it not return in the first >> loop. So add a break at the end of the loop. >> >> Can you explain why? If it is the case, MIGRATE_UNMOVABLE cannot fall back >> to MIGRATE_MOVABLE? And MIGRATE_MOVABLE cannot fall back to MIGRATE_UNMOVABLE? >> And MIGRATE_RECLAIMABLE cannot fall back to MIGRATE_MOVABLE? >> The return in the loop is only related to 'order', 'migratetype' and 'only_stealable' >> variables. Even if it execute the next loop, it can't change the result. So the loop >> can be broken if the first loop can't return. >> >> OK. Got it. Would the code below look better? >> >> for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { >> fallback_mt = fallbacks[migratetype][i]; >> if (free_area_empty(area, fallback_mt)) >> continue; >> } >> >> if (can_steal_fallback(order, migratetype)) >> *can_steal = true; >> >> if (!only_stealable || *can_steal) >> return fallback_mt; >> >> return -1; >>> Yes, I'll submit a v3 patch. >>> Thanks. >> >> I found a logical error in your code. It should be like this: >> >> for (i = 0; i < MIGRATE_PCPTYPES - 1 ; i++) { >> fallback_mt = fallbacks[migratetype][i]; >> if (!free_area_empty(area, fallback_mt)) >> break; >> } >> >> if (can_steal_fallback(order, migratetype)) >> *can_steal = true; >> >> if (!only_stealable || *can_steal) >> return fallback_mt; >> >> return -1; >> >> This code will modify the logic to the opposite. > > It's still wrong, IMHO. If all fallbacks have free_area_empty(), it will > return the last one and not -1. Also will set *can_steal in such case. > Yes, you are right. >> So can anyone tell me if I should use this code or the v2 patch? > > Once that bugs are fixed, the result will probably not look much better than > v2, so I don't mind keeping v2. I agree with that.
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index ab94985ee7d9..0a817b8c7fb2 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -85,7 +85,7 @@ static inline bool is_migrate_movable(int mt) * Check whether a migratetype can be merged with another migratetype. * * It is only mergeable when it can fall back to other migratetypes for - * allocation. See fallbacks[MIGRATE_TYPES][3] in page_alloc.c. + * allocation. See fallbacks[][] array in page_alloc.c. */ static inline bool migratetype_is_mergeable(int mt) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1113483fa6c5..536e8d838fb5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2603,7 +2603,7 @@ struct page *__rmqueue_smallest(struct zone *zone, unsigned int order, * * The other migratetypes do not have fallbacks. */ -static int fallbacks[MIGRATE_TYPES][MIGRATE_PCPTYPES - 1] = { +static int fallbacks[MIGRATE_PCPTYPES][MIGRATE_PCPTYPES - 1] = { [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE }, [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE }, [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE }, @@ -2861,7 +2861,7 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, int i; int fallback_mt; - if (area->nr_free == 0) + if (area->nr_free == 0 || !migratetype_is_mergeable(migratetype)) return -1; *can_steal = false; @@ -2873,11 +2873,10 @@ int find_suitable_fallback(struct free_area *area, unsigned int order, if (can_steal_fallback(order, migratetype)) *can_steal = true; - if (!only_stealable) - return fallback_mt; - - if (*can_steal) + if (!only_stealable || *can_steal) return fallback_mt; + else + break; } return -1;