diff --git a/include/linux/mm.h b/include/linux/mm.h index 878a516f2267bb..d6cd2febad4122 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1619,6 +1619,17 @@ static inline bool folio_maybe_dma_pinned(struct folio *folio) if (folio_test_large(folio)) return atomic_read(folio_pincount_ptr(folio)) > 0; + /* + * We only allow pinning anonymous pages (see gup_must_unshare()) + * while they have the exclusive marker set and don't allow clearing the + * exclusive marker while they maybe pinned (see + * page_try_share_anon_rmap() and page_try_dup_anon_rmap()). + * Consequently, pages with the exclusive marker cleared cannot be + * pinned and we can optimize for that case here. + */ + if (folio_test_anon(folio) && !PageAnonExclusive(&folio->page)) + return false; + /* * folio_ref_count() is signed. If that refcount overflows, then * folio_ref_count() returns a negative value, and callers will avoid