From nobody Sat Apr 11 06:35:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 382D2C282E7 for ; Mon, 15 Aug 2022 07:02:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241276AbiHOHCe (ORCPT ); Mon, 15 Aug 2022 03:02:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36024 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241254AbiHOHCc (ORCPT ); Mon, 15 Aug 2022 03:02:32 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E09DEA0 for ; Mon, 15 Aug 2022 00:02:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660546951; x=1692082951; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6y3vJM03inTN3n4fTtr3sj64MkkloN/gZvJBPW9m2l0=; b=dIrfVjlHj2h0aSKI+F0HK7c9chMOayaR3RY+VGYSPt/hyYglmEVlF+Wx pXmE+ebnDGGgzB2Q1nHfTmJ5aULsWbUJyvNpgBahg+HysHt15I5VqpF0X gXY3uBU2v3CZwn29/WC5egYTUwzANMnC30OWomydorZrUF5TF2akOZmNd 4B3JH03EkUzf81Y9kJhxYbnQEBUyTFIY8iAKzBg1RXwugBVyZnp2w0cj5 eeXs6i1jCioZUL7Dk2x1ueGD9ZQrkoCQUIqkhyXB1ZXu4m+w6M7LcoZGZ HnGsy+efy1CpD9OelA+iYuPUlejxYtFh7dX29X+XgBwoCBJ4raT5Xg3B1 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10439"; a="274960253" X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="274960253" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Aug 2022 00:02:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="666566767" Received: from sse-cse-haiyue-nuc.sh.intel.com ([10.239.241.114]) by fmsmga008.fm.intel.com with ESMTP; 15 Aug 2022 00:02:27 -0700 From: Haiyue Wang To: linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: akpm@linux-foundation.org, david@redhat.com, apopple@nvidia.com, linmiaohe@huawei.com, ying.huang@intel.com, songmuchun@bytedance.com, naoya.horiguchi@linux.dev, alex.sierra@amd.com, Haiyue Wang Subject: [PATCH v5 1/2] mm: migration: fix the FOLL_GET failure on following huge page Date: Mon, 15 Aug 2022 15:02:39 +0800 Message-Id: <20220815070240.470469-2-haiyue.wang@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815070240.470469-1-haiyue.wang@intel.com> References: <20220812084921.409142-1-haiyue.wang@intel.com> <20220815070240.470469-1-haiyue.wang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Not all huge page APIs support FOLL_GET option, so move_pages() syscall will fail to get the page node information for some huge pages. Like x86 on linux 5.19 with 1GB huge page API follow_huge_pud(), it will return NULL page for FOLL_GET when calling move_pages() syscall with the NULL 'nodes' parameter, the 'status' parameter has '-2' error in array. Note: follow_huge_pud() now supports FOLL_GET in linux 6.0. Link: https://lore.kernel.org/all/20220714042420.1847125-3-naoya.hori= guchi@linux.dev But these huge page APIs don't support FOLL_GET: 1. follow_huge_pud() in arch/s390/mm/hugetlbpage.c 2. follow_huge_addr() in arch/ia64/mm/hugetlbpage.c It will cause WARN_ON_ONCE for FOLL_GET. 3. follow_huge_pgd() in mm/hugetlb.c This is an temporary solution to mitigate the side effect of the race condition fix by calling follow_page() with FOLL_GET set for huge pages. After supporting follow huge page by FOLL_GET is done, this fix can be reverted safely. Fixes: 4cd614841c06 ("mm: migration: fix possible do_pages_stat_array racin= g with memory offline") Signed-off-by: Haiyue Wang Reviewed-by: "Huang, Ying" --- mm/migrate.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mm/migrate.c b/mm/migrate.c index 6a1597c92261..581dfaad9257 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1848,6 +1848,7 @@ static void do_pages_stat_array(struct mm_struct *mm,= unsigned long nr_pages, =20 for (i =3D 0; i < nr_pages; i++) { unsigned long addr =3D (unsigned long)(*pages); + unsigned int foll_flags =3D FOLL_DUMP; struct vm_area_struct *vma; struct page *page; int err =3D -EFAULT; @@ -1856,8 +1857,12 @@ static void do_pages_stat_array(struct mm_struct *mm= , unsigned long nr_pages, if (!vma) goto set_status; =20 + /* Not all huge page follow APIs support 'FOLL_GET' */ + if (!is_vm_hugetlb_page(vma)) + foll_flags |=3D FOLL_GET; + /* FOLL_DUMP to ignore special (like zero) pages */ - page =3D follow_page(vma, addr, FOLL_GET | FOLL_DUMP); + page =3D follow_page(vma, addr, foll_flags); =20 err =3D PTR_ERR(page); if (IS_ERR(page)) @@ -1865,7 +1870,8 @@ static void do_pages_stat_array(struct mm_struct *mm,= unsigned long nr_pages, =20 if (page && !is_zone_device_page(page)) { err =3D page_to_nid(page); - put_page(page); + if (foll_flags & FOLL_GET) + put_page(page); } else { err =3D -ENOENT; } --=20 2.37.2 From nobody Sat Apr 11 06:35:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69C61C00140 for ; Mon, 15 Aug 2022 07:02:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241287AbiHOHCi (ORCPT ); Mon, 15 Aug 2022 03:02:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241275AbiHOHCe (ORCPT ); Mon, 15 Aug 2022 03:02:34 -0400 Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4D3A1C135 for ; Mon, 15 Aug 2022 00:02:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660546953; x=1692082953; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=3RyMMTN/AHHSqtfx+jaKLw7DbxnmzdBDsCyu34bLAqQ=; b=FxGtrw/rENG96QOw9t3WWxrBRVP5IhFCBQ94iZOAbBKpNbh7z1eAk/ER 62UOs4w9Cv6h66M/pla9IlWi2NdT6xODypBu7ssQ08pJbplDlgtBoCzCk zDivy1fW3lj5ljQMBRHB1mDls+y2EnrLYm1tfjXVo+OTHElp+WAaXSL1D cCsjnZ8/YOmNUmDQXFnB8fQiEKZtOY/Er1JsIzKZimM8Y99wvPg5zUSdt 5RO/LURgDQAUEvEV4eeoHwrQAS6uValmBDHikLFV/VuEnz+Xu6/oqVGCd tSSRTRzrwQ/M4Oh8kobFmPYFzGI9+moQRQSAu6oI2r4+GNlcDWBg14k/e Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10439"; a="274960263" X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="274960263" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Aug 2022 00:02:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,237,1654585200"; d="scan'208";a="666566780" Received: from sse-cse-haiyue-nuc.sh.intel.com ([10.239.241.114]) by fmsmga008.fm.intel.com with ESMTP; 15 Aug 2022 00:02:30 -0700 From: Haiyue Wang To: linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: akpm@linux-foundation.org, david@redhat.com, apopple@nvidia.com, linmiaohe@huawei.com, ying.huang@intel.com, songmuchun@bytedance.com, naoya.horiguchi@linux.dev, alex.sierra@amd.com, Haiyue Wang , Felix Kuehling Subject: [PATCH v5 2/2] mm: fix the handling Non-LRU pages returned by follow_page Date: Mon, 15 Aug 2022 15:02:40 +0800 Message-Id: <20220815070240.470469-3-haiyue.wang@intel.com> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20220815070240.470469-1-haiyue.wang@intel.com> References: <20220812084921.409142-1-haiyue.wang@intel.com> <20220815070240.470469-1-haiyue.wang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The handling Non-LRU pages returned by follow_page() jumps directly, it doesn't call put_page() to handle the reference count, since 'FOLL_GET' flag for follow_page() has get_page() called. Fix the zone device page check by handling the page reference count correctly before returning. And as David reviewed, "device pages are never PageKsm pages". Drop this zone device page check for break_ksm(). Fixes: 3218f8712d6b ("mm: handling Non-LRU pages returned by vm_normal_page= s") Signed-off-by: Haiyue Wang Reviewed-by: "Huang, Ying" Reviewed-by: Felix Kuehling --- mm/huge_memory.c | 4 ++-- mm/ksm.c | 12 +++++++++--- mm/migrate.c | 10 +++++++--- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 8a7c1b344abe..b2ba17c3dcd7 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2963,10 +2963,10 @@ static int split_huge_pages_pid(int pid, unsigned l= ong vaddr_start, /* FOLL_DUMP to ignore special (like zero) pages */ page =3D follow_page(vma, addr, FOLL_GET | FOLL_DUMP); =20 - if (IS_ERR_OR_NULL(page) || is_zone_device_page(page)) + if (IS_ERR_OR_NULL(page)) continue; =20 - if (!is_transparent_hugepage(page)) + if (is_zone_device_page(page) || !is_transparent_hugepage(page)) goto next; =20 total++; diff --git a/mm/ksm.c b/mm/ksm.c index 42ab153335a2..e26f57fc1f0e 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -475,7 +475,7 @@ static int break_ksm(struct vm_area_struct *vma, unsign= ed long addr) cond_resched(); page =3D follow_page(vma, addr, FOLL_GET | FOLL_MIGRATION | FOLL_REMOTE); - if (IS_ERR_OR_NULL(page) || is_zone_device_page(page)) + if (IS_ERR_OR_NULL(page)) break; if (PageKsm(page)) ret =3D handle_mm_fault(vma, addr, @@ -560,12 +560,15 @@ static struct page *get_mergeable_page(struct rmap_it= em *rmap_item) goto out; =20 page =3D follow_page(vma, addr, FOLL_GET); - if (IS_ERR_OR_NULL(page) || is_zone_device_page(page)) + if (IS_ERR_OR_NULL(page)) goto out; + if (is_zone_device_page(page)) + goto out_putpage; if (PageAnon(page)) { flush_anon_page(vma, page, addr); flush_dcache_page(page); } else { +out_putpage: put_page(page); out: page =3D NULL; @@ -2308,11 +2311,13 @@ static struct rmap_item *scan_get_next_rmap_item(st= ruct page **page) if (ksm_test_exit(mm)) break; *page =3D follow_page(vma, ksm_scan.address, FOLL_GET); - if (IS_ERR_OR_NULL(*page) || is_zone_device_page(*page)) { + if (IS_ERR_OR_NULL(*page)) { ksm_scan.address +=3D PAGE_SIZE; cond_resched(); continue; } + if (is_zone_device_page(*page)) + goto next_page; if (PageAnon(*page)) { flush_anon_page(vma, *page, ksm_scan.address); flush_dcache_page(*page); @@ -2327,6 +2332,7 @@ static struct rmap_item *scan_get_next_rmap_item(stru= ct page **page) mmap_read_unlock(mm); return rmap_item; } +next_page: put_page(*page); ksm_scan.address +=3D PAGE_SIZE; cond_resched(); diff --git a/mm/migrate.c b/mm/migrate.c index 581dfaad9257..fee12cd2f294 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1672,9 +1672,12 @@ static int add_page_for_migration(struct mm_struct *= mm, unsigned long addr, goto out; =20 err =3D -ENOENT; - if (!page || is_zone_device_page(page)) + if (!page) goto out; =20 + if (is_zone_device_page(page)) + goto out_putpage; + err =3D 0; if (page_to_nid(page) =3D=3D node) goto out_putpage; @@ -1868,8 +1871,9 @@ static void do_pages_stat_array(struct mm_struct *mm,= unsigned long nr_pages, if (IS_ERR(page)) goto set_status; =20 - if (page && !is_zone_device_page(page)) { - err =3D page_to_nid(page); + if (page) { + err =3D !is_zone_device_page(page) ? page_to_nid(page) + : -ENOENT; if (foll_flags & FOLL_GET) put_page(page); } else { --=20 2.37.2