Commit 2835d460 authored by Matthew Wilcox (Oracle)'s avatar Matthew Wilcox (Oracle) Committed by Liu Shixin
Browse files

mm: always initialise folio->_deferred_list

mainline inclusion
from mainline-v6.10-rc1
commit b7b098cf00a2b65d5654a86dc8edf82f125289c1
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9R3AY
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b7b098cf00a2b65d5654a86dc8edf82f125289c1

--------------------------------

Patch series "Various significant MM patches".

These patches all interact in annoying ways which make it tricky to send
them out in any way other than a big batch, even though there's not really
an overarching theme to connect them.

The big effects of this patch series are:

 - folio_test_hugetlb() becomes reliable, even when called without a
   page reference
 - We free up PG_slab, and we could always use more page flags
 - We no longer need to check PageSlab before calling page_mapcount()

This patch (of 9):

For compound pages which are at least order-2 (and hence have a
deferred_list), initialise it and then we can check at free that the page
is not part of a deferred list.  We recently found this useful to rule out
a source of corruption.

[peterx@redhat.com: always initialise folio->_deferred_list]
  Link: https://lkml.kernel.org/r/20240417211836.2742593-2-peterx@redhat.com
Link: https://lkml.kernel.org/r/20240321142448.1645400-1-willy@infradead.org
Link: https://lkml.kernel.org/r/20240321142448.1645400-2-willy@infradead.org


Signed-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 9e4e4615
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -952,8 +952,6 @@ void folio_prep_large_rmappable(struct folio *folio)
{
	if (!folio || !folio_test_large(folio))
		return;
	if (folio_order(folio) > 1)
		INIT_LIST_HEAD(&folio->_deferred_list);
	folio_set_large_rmappable(folio);
}

+2 −1
Original line number Diff line number Diff line
@@ -1804,7 +1804,8 @@ static void __update_and_free_hugetlb_folio(struct hstate *h,
		destroy_compound_gigantic_folio(folio, huge_page_order(h));
		free_gigantic_folio(folio, huge_page_order(h));
	} else {
		__free_pages(&folio->page, huge_page_order(h));
		INIT_LIST_HEAD(&folio->_deferred_list);
		folio_put(folio);
	}
}

+2 −0
Original line number Diff line number Diff line
@@ -610,6 +610,8 @@ static inline void prep_compound_head(struct page *page, unsigned int order)
	atomic_set(&folio->_entire_mapcount, -1);
	atomic_set(&folio->_nr_pages_mapped, 0);
	atomic_set(&folio->_pincount, 0);
	if (order > 1)
		INIT_LIST_HEAD(&folio->_deferred_list);
}

static inline void prep_compound_tail(struct page *head, int tail_idx)
+3 −0
Original line number Diff line number Diff line
@@ -8518,6 +8518,9 @@ static void uncharge_folio(struct folio *folio, struct uncharge_gather *ug)
	struct obj_cgroup *objcg;

	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
	VM_BUG_ON_FOLIO(folio_order(folio) > 1 &&
			!folio_test_hugetlb(folio) &&
			!list_empty(&folio->_deferred_list), folio);

	/*
	 * Nobody should be changing or seriously looking at
+5 −4
Original line number Diff line number Diff line
@@ -986,10 +986,11 @@ static int free_tail_page_prepare(struct page *head_page, struct page *page)
		}
		break;
	case 2:
		/*
		 * the second tail page: ->mapping is
		 * deferred_list.next -- ignore value.
		 */
		/* the second tail page: deferred_list overlaps ->mapping */
		if (unlikely(!list_empty(&folio->_deferred_list))) {
			bad_page(page, "on deferred list");
			goto out;
		}
		break;
	default:
		if (page->mapping != TAIL_MAPPING) {