diff options
author | Alex Williamson <[email protected]> | 2022-08-10 10:53:59 -0600 |
---|---|---|
committer | Andrew Morton <[email protected]> | 2022-08-28 14:02:44 -0700 |
commit | fcab34b433e2c13e333b2f53c4a8409eadc432c7 (patch) | |
tree | f41557fa60c6d91fbd04fa4a057e1498476264e9 | |
parent | f09bddbd86619bf6213c96142a3b6b6a84818798 (diff) |
mm: re-allow pinning of zero pfns (again)
The below referenced commit makes the same error as 1c563432588d ("mm: fix
is_pinnable_page against a cma page"), re-interpreting the logic to
exclude pinning of the zero page, which breaks device assignment with
vfio.
To avoid further subtle mistakes, split the logic into discrete tests.
[[email protected]: simplify comment, per John]
Link: https://lkml.kernel.org/r/166015037385.760108.16881097713975517242.stgit@omen
Link: https://lore.kernel.org/all/165490039431.944052.12458624139225785964.stgit@omen
Fixes: f25cbb7a95a2 ("mm: add zone device coherent type memory support")
Signed-off-by: Alex Williamson <[email protected]>
Suggested-by: Matthew Wilcox <[email protected]>
Suggested-by: Felix Kuehling <[email protected]>
Tested-by: Slawomir Laba <[email protected]>
Reviewed-by: John Hubbard <[email protected]>
Cc: Alex Sierra <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Alistair Popple <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
-rw-r--r-- | include/linux/mm.h | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h index 982f2607180b..21f8b27bd9fd 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1544,9 +1544,16 @@ static inline bool is_longterm_pinnable_page(struct page *page) if (mt == MIGRATE_CMA || mt == MIGRATE_ISOLATE) return false; #endif - return !(is_device_coherent_page(page) || - is_zone_movable_page(page) || - is_zero_pfn(page_to_pfn(page))); + /* The zero page may always be pinned */ + if (is_zero_pfn(page_to_pfn(page))) + return true; + + /* Coherent device memory must always allow eviction. */ + if (is_device_coherent_page(page)) + return false; + + /* Otherwise, non-movable zone pages can be pinned. */ + return !is_zone_movable_page(page); } #else static inline bool is_longterm_pinnable_page(struct page *page) |