| From: Peter Xu <peterx@redhat.com> |
| Subject: mm/migrate: putback split folios when numa hint migration fails |
| Date: Mon, 8 Jul 2024 17:55:37 -0400 |
| |
| This issue is not from any report yet, but by code observation only. |
| |
| This is yet another fix besides Hugh's patch [1] but on relevant code |
| path, where eager split of folio can happen if the folio is already on |
| deferred list during a folio migration. |
| |
| Here the issue is NUMA path (migrate_misplaced_folio()) may start to |
| encounter such folio split now even with MR_NUMA_MISPLACED hint applied. |
| Then when migrate_pages() didn't migrate all the folios, it's possible the |
| split small folios be put onto the list instead of the original folio. |
| Then putting back only the head page won't be enough. |
| |
| Fix it by putting back all the folios on the list. |
| |
| [1] https://lore.kernel.org/all/46c948b4-4dd8-6e03-4c7b-ce4e81cfa536@google.com/ |
| |
| [akpm@linux-foundation.org: remove now unused local `nr_pages'] |
| Link: https://lkml.kernel.org/r/20240708215537.2630610-1-peterx@redhat.com |
| Fixes: 7262f208ca68 ("mm/migrate: split source folio if it is on deferred split list") |
| Signed-off-by: Peter Xu <peterx@redhat.com> |
| Reviewed-by: Zi Yan <ziy@nvidia.com> |
| Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com> |
| Cc: Yang Shi <shy828301@gmail.com> |
| Cc: Hugh Dickins <hughd@google.com> |
| Cc: Huang Ying <ying.huang@intel.com> |
| Cc: David Hildenbrand <david@redhat.com> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/migrate.c | 11 ++--------- |
| 1 file changed, 2 insertions(+), 9 deletions(-) |
| |
| --- a/mm/migrate.c~mm-migrate-putback-split-folios-when-numa-hint-migration-fails |
| +++ a/mm/migrate.c |
| @@ -2621,20 +2621,13 @@ int migrate_misplaced_folio(struct folio |
| int nr_remaining; |
| unsigned int nr_succeeded; |
| LIST_HEAD(migratepages); |
| - int nr_pages = folio_nr_pages(folio); |
| |
| list_add(&folio->lru, &migratepages); |
| nr_remaining = migrate_pages(&migratepages, alloc_misplaced_dst_folio, |
| NULL, node, MIGRATE_ASYNC, |
| MR_NUMA_MISPLACED, &nr_succeeded); |
| - if (nr_remaining) { |
| - if (!list_empty(&migratepages)) { |
| - list_del(&folio->lru); |
| - node_stat_mod_folio(folio, NR_ISOLATED_ANON + |
| - folio_is_file_lru(folio), -nr_pages); |
| - folio_putback_lru(folio); |
| - } |
| - } |
| + if (nr_remaining && !list_empty(&migratepages)) |
| + putback_movable_pages(&migratepages); |
| if (nr_succeeded) { |
| count_vm_numa_events(NUMA_PAGE_MIGRATE, nr_succeeded); |
| if (!node_is_toptier(folio_nid(folio)) && node_is_toptier(node)) |
| _ |