2023-08-26 13:56:54

by Kemeng Shi

[permalink] [raw]
Subject: [PATCH v2 0/7] Fixes and cleanups to compaction

Hi all, this is another series to do fix and clean up to compaction.
Patch 1-2 fix and clean up freepage list operation.
Patch 3-4 fix and clean up isolation of freepages
Patch 7 factor code to check if compaction is needed for allocation
order.
More details can be found in respective patches. Thanks!

v1->v2:
-Collect RVB from Baolin.
-Keep pfn inside of pageblock in patch 3.
-Only improve comment of is_via_compact_memory in patch 6.
-Squash patch 8 and patch 9 into patch 7 and use ALLOC_WMARK_MIN
instead of magic number 0.

Kemeng Shi (7):
mm/compaction: use correct list in move_freelist_{head}/{tail}
mm/compaction: call list_is_{first}/{last} more intuitively in
move_freelist_{head}/{tail}
mm/compaction: correctly return failure with bogus compound_order in
strict mode
mm/compaction: simplify pfn iteration in isolate_freepages_range
mm/compaction: remove repeat compact_blockskip_flush check in
reset_isolation_suitable
mm/compaction: improve comment of is_via_compact_memory
mm/compaction: factor out code to test if we should run compaction for
target order

mm/compaction.c | 106 +++++++++++++++++++++++++-----------------------
1 file changed, 56 insertions(+), 50 deletions(-)

--
2.30.0



2023-08-26 14:02:25

by Kemeng Shi

[permalink] [raw]
Subject: [PATCH v2 2/7] mm/compaction: call list_is_{first}/{last} more intuitively in move_freelist_{head}/{tail}

We use move_freelist_head after list_for_each_entry_reverse to skip
recent pages. And there is no need to do actual move if all freepages
are searched in list_for_each_entry_reverse, e.g. freepage point to
first page in freelist. It's more intuitively to call list_is_first
with list entry as the first argument and list head as the second
argument to check if list entry is the first list entry instead of
call list_is_last with list entry and list head passed in reverse.

Similarly, call list_is_last in move_freelist_tail is more intuitively.

Signed-off-by: Kemeng Shi <[email protected]>
Reviewed-by: Baolin Wang <[email protected]>
---
mm/compaction.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index e3ee1bc1c0ad..a40550a33aee 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1395,7 +1395,7 @@ move_freelist_head(struct list_head *freelist, struct page *freepage)
{
LIST_HEAD(sublist);

- if (!list_is_last(freelist, &freepage->buddy_list)) {
+ if (!list_is_first(&freepage->buddy_list, freelist)) {
list_cut_before(&sublist, freelist, &freepage->buddy_list);
list_splice_tail(&sublist, freelist);
}
@@ -1412,7 +1412,7 @@ move_freelist_tail(struct list_head *freelist, struct page *freepage)
{
LIST_HEAD(sublist);

- if (!list_is_first(freelist, &freepage->buddy_list)) {
+ if (!list_is_last(&freepage->buddy_list, freelist)) {
list_cut_position(&sublist, freelist, &freepage->buddy_list);
list_splice_tail(&sublist, freelist);
}
--
2.30.0


2023-08-26 14:04:19

by Kemeng Shi

[permalink] [raw]
Subject: [PATCH v2 6/7] mm/compaction: improve comment of is_via_compact_memory

We do proactive compaction with order == -1 via
1. /proc/sys/vm/compact_memory
2. /sys/devices/system/node/nodex/compact
3. /proc/sys/vm/compaction_proactiveness
Add missed situation in which order == -1.

Signed-off-by: Kemeng Shi <[email protected]>
---
mm/compaction.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index 89a1b627bc89..00b7bba6c72e 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -2061,8 +2061,10 @@ static isolate_migrate_t isolate_migratepages(struct compact_control *cc)
}

/*
- * order == -1 is expected when compacting via
- * /proc/sys/vm/compact_memory
+ * order == -1 is expected when compacting proactively via
+ * 1. /proc/sys/vm/compact_memory
+ * 2. /sys/devices/system/node/nodex/compact
+ * 3. /proc/sys/vm/compaction_proactiveness
*/
static inline bool is_via_compact_memory(int order)
{
--
2.30.0


2023-08-26 14:20:33

by Kemeng Shi

[permalink] [raw]
Subject: [PATCH v2 4/7] mm/compaction: simplify pfn iteration in isolate_freepages_range

We call isolate_freepages_block in strict mode, continuous pages in
pageblock will be isolated if isolate_freepages_block successed.
Then pfn + isolated will point to start of next pageblock to scan
no matter how many pageblocks are isolated in isolate_freepages_block.
Use pfn + isolated as start of next pageblock to scan to simplify the
iteration.

The pfn + isolated always points to start of next pageblock as:
In case isolated buddy page has order higher than pageblock:
1. page in buddy page is aligned with it's order
2. order of page is higher than pageblock order
Then page is aligned with pageblock order. So pfn of page and isolated
pages count are both aligned pageblock order. So pfn + isolated is
pageblock order aligned.

In case isolated buddy page has order lower than pageblock:
Buddy page with order N contains two order N - 1 pages as following:
| order N |
|order N - 1|order N - 1|
So buddy pages with order N - 1 will never cross boudary of order N.
Similar, buddy pages with order N - 2 will never cross boudary of order
N - 1 and so on. Then any pages with order less than pageblock order
will never crosa boudary of pageblock.

Signed-off-by: Kemeng Shi <[email protected]>
Reviewed-by: Baolin Wang <[email protected]>
---
mm/compaction.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index b4d03c9ffe7c..2937e754cfb7 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -739,21 +739,11 @@ isolate_freepages_range(struct compact_control *cc,
block_end_pfn = pageblock_end_pfn(pfn);

for (; pfn < end_pfn; pfn += isolated,
- block_start_pfn = block_end_pfn,
- block_end_pfn += pageblock_nr_pages) {
+ block_start_pfn = pfn,
+ block_end_pfn = pfn + pageblock_nr_pages) {
/* Protect pfn from changing by isolate_freepages_block */
unsigned long isolate_start_pfn = pfn;

- /*
- * pfn could pass the block_end_pfn if isolated freepage
- * is more than pageblock order. In this case, we adjust
- * scanning range to right one.
- */
- if (pfn >= block_end_pfn) {
- block_start_pfn = pageblock_start_pfn(pfn);
- block_end_pfn = pageblock_end_pfn(pfn);
- }
-
block_end_pfn = min(block_end_pfn, end_pfn);

if (!pageblock_pfn_to_page(block_start_pfn,
--
2.30.0


2023-08-29 12:11:36

by Mel Gorman

[permalink] [raw]
Subject: Re: [PATCH v2 2/7] mm/compaction: call list_is_{first}/{last} more intuitively in move_freelist_{head}/{tail}

On Sat, Aug 26, 2023 at 11:36:12PM +0800, Kemeng Shi wrote:
> We use move_freelist_head after list_for_each_entry_reverse to skip
> recent pages. And there is no need to do actual move if all freepages
> are searched in list_for_each_entry_reverse, e.g. freepage point to
> first page in freelist. It's more intuitively to call list_is_first
> with list entry as the first argument and list head as the second
> argument to check if list entry is the first list entry instead of
> call list_is_last with list entry and list head passed in reverse.
>
> Similarly, call list_is_last in move_freelist_tail is more intuitively.
>
> Signed-off-by: Kemeng Shi <[email protected]>
> Reviewed-by: Baolin Wang <[email protected]>

Acked-by: Mel Gorman <[email protected]>

--
Mel Gorman
SUSE Labs

2023-08-29 19:03:04

by Mel Gorman

[permalink] [raw]
Subject: Re: [PATCH v2 6/7] mm/compaction: improve comment of is_via_compact_memory

On Sat, Aug 26, 2023 at 11:36:16PM +0800, Kemeng Shi wrote:
> We do proactive compaction with order == -1 via
> 1. /proc/sys/vm/compact_memory
> 2. /sys/devices/system/node/nodex/compact
> 3. /proc/sys/vm/compaction_proactiveness
> Add missed situation in which order == -1.
>
> Signed-off-by: Kemeng Shi <[email protected]>

Acked-by: Mel Gorman <[email protected]>

--
Mel Gorman
SUSE Labs

2023-08-29 19:15:38

by Mel Gorman

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] mm/compaction: simplify pfn iteration in isolate_freepages_range

On Sat, Aug 26, 2023 at 11:36:14PM +0800, Kemeng Shi wrote:
> We call isolate_freepages_block in strict mode, continuous pages in
> pageblock will be isolated if isolate_freepages_block successed.
> Then pfn + isolated will point to start of next pageblock to scan
> no matter how many pageblocks are isolated in isolate_freepages_block.
> Use pfn + isolated as start of next pageblock to scan to simplify the
> iteration.
>
> The pfn + isolated always points to start of next pageblock as:
> In case isolated buddy page has order higher than pageblock:
> 1. page in buddy page is aligned with it's order
> 2. order of page is higher than pageblock order
> Then page is aligned with pageblock order. So pfn of page and isolated
> pages count are both aligned pageblock order. So pfn + isolated is
> pageblock order aligned.
>
> In case isolated buddy page has order lower than pageblock:
> Buddy page with order N contains two order N - 1 pages as following:
> | order N |
> |order N - 1|order N - 1|
> So buddy pages with order N - 1 will never cross boudary of order N.
> Similar, buddy pages with order N - 2 will never cross boudary of order
> N - 1 and so on. Then any pages with order less than pageblock order
> will never crosa boudary of pageblock.
>
> Signed-off-by: Kemeng Shi <[email protected]>
> Reviewed-by: Baolin Wang <[email protected]>

While I don't think the patch is wrong, I also don't think it
meaningfully simplifies the code or optimises enough to be justified.
Even though a branch is eliminated, the whole path is not cheap.

--
Mel Gorman
SUSE Labs

2023-08-30 18:53:18

by Kemeng Shi

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] mm/compaction: simplify pfn iteration in isolate_freepages_range



on 8/29/2023 11:01 PM, Mel Gorman wrote:
> On Sat, Aug 26, 2023 at 11:36:14PM +0800, Kemeng Shi wrote:
>> We call isolate_freepages_block in strict mode, continuous pages in
>> pageblock will be isolated if isolate_freepages_block successed.
>> Then pfn + isolated will point to start of next pageblock to scan
>> no matter how many pageblocks are isolated in isolate_freepages_block.
>> Use pfn + isolated as start of next pageblock to scan to simplify the
>> iteration.
>>
>> The pfn + isolated always points to start of next pageblock as:
>> In case isolated buddy page has order higher than pageblock:
>> 1. page in buddy page is aligned with it's order
>> 2. order of page is higher than pageblock order
>> Then page is aligned with pageblock order. So pfn of page and isolated
>> pages count are both aligned pageblock order. So pfn + isolated is
>> pageblock order aligned.
>>
>> In case isolated buddy page has order lower than pageblock:
>> Buddy page with order N contains two order N - 1 pages as following:
>> | order N |
>> |order N - 1|order N - 1|
>> So buddy pages with order N - 1 will never cross boudary of order N.
>> Similar, buddy pages with order N - 2 will never cross boudary of order
>> N - 1 and so on. Then any pages with order less than pageblock order
>> will never crosa boudary of pageblock.
>>
>> Signed-off-by: Kemeng Shi <[email protected]>
>> Reviewed-by: Baolin Wang <[email protected]>
>
> While I don't think the patch is wrong, I also don't think it
> meaningfully simplifies the code or optimises enough to be justified.
> Even though a branch is eliminated, the whole path is not cheap.
>
OK, I will drop this in next version if you insistant.