summaryrefslogtreecommitdiffstats
path: root/mm/gup.c
diff options
context:
space:
mode:
authorMatthew Wilcox (Oracle) <willy@infradead.org>2022-02-04 09:24:26 -0500
committerMatthew Wilcox (Oracle) <willy@infradead.org>2022-03-21 12:56:34 -0400
commit8ea2979c1444cd455ddbe7f976de79cc09fdc38d (patch)
tree984f8232835647aab7eb9501927174c03fd2c72c /mm/gup.c
parentd90a25f86dc83df9ce7f1446372cda8029e87f7c (diff)
downloadlinux-8ea2979c1444cd455ddbe7f976de79cc09fdc38d.tar.bz2
mm/gup: Increment the page refcount before the pincount
We should always increase the refcount before doing anything else to the page so that other page users see the elevated refcount first. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: John Hubbard <jhubbard@nvidia.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'mm/gup.c')
-rw-r--r--mm/gup.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/mm/gup.c b/mm/gup.c
index e54359ef75ac..eb7747bc7f7d 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -213,25 +213,23 @@ bool __must_check try_grab_page(struct page *page, unsigned int flags)
if (flags & FOLL_GET)
return try_get_page(page);
else if (flags & FOLL_PIN) {
- int refs = 1;
-
page = compound_head(page);
if (WARN_ON_ONCE(page_ref_count(page) <= 0))
return false;
- if (hpage_pincount_available(page))
- hpage_pincount_add(page, 1);
- else
- refs = GUP_PIN_COUNTING_BIAS;
-
/*
* Similar to try_grab_compound_head(): even if using the
* hpage_pincount_add/_sub() routines, be sure to
* *also* increment the normal page refcount field at least
* once, so that the page really is pinned.
*/
- page_ref_add(page, refs);
+ if (hpage_pincount_available(page)) {
+ page_ref_add(page, 1);
+ hpage_pincount_add(page, 1);
+ } else {
+ page_ref_add(page, GUP_PIN_COUNTING_BIAS);
+ }
mod_node_page_state(page_pgdat(page), NR_FOLL_PIN_ACQUIRED, 1);
}