From: Zi Yan <z...@nvidia.com>

In isolate_migratepages_block(), a !PageLRU tail page can be encountered
when the page is larger than a pageblock. Use compound head page for the
checks inside and skip the entire compound page when isolation succeeds.

Signed-off-by: Zi Yan <z...@nvidia.com>
---
 mm/compaction.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/mm/compaction.c b/mm/compaction.c
index b4e94cda3019..ad9053fbbe06 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -979,19 +979,23 @@ isolate_migratepages_block(struct compact_control *cc, 
unsigned long low_pfn,
                 * Skip any other type of page
                 */
                if (!PageLRU(page)) {
+                       struct page *head = compound_head(page);
                        /*
                         * __PageMovable can return false positive so we need
                         * to verify it under page_lock.
                         */
-                       if (unlikely(__PageMovable(page)) &&
-                                       !PageIsolated(page)) {
+                       if (unlikely(__PageMovable(head)) &&
+                                       !PageIsolated(head)) {
                                if (locked) {
                                        unlock_page_lruvec_irqrestore(locked, 
flags);
                                        locked = NULL;
                                }
 
-                               if (!isolate_movable_page(page, isolate_mode))
+                               if (!isolate_movable_page(head, isolate_mode)) {
+                                       low_pfn += (1 << compound_order(head)) 
- 1 - (page - head);
+                                       page = head;
                                        goto isolate_success;
+                               }
                        }
 
                        goto isolate_fail;
-- 
2.33.0

Reply via email to