Skip to content

Commit 503670e

Browse files
VMoolaakpm00
authored andcommitted
mm/gup.c: reorganize try_get_folio()
try_get_folio() takes in a page, then chooses to do some folio operations based on the flags (either FOLL_GET or FOLL_PIN). We can rewrite this function to be more purpose oriented. After calling try_get_folio(), if neither FOLL_GET nor FOLL_PIN are set, warn and fail. If FOLL_GET is set we can return the result. If FOLL_GET is not set then FOLL_PIN is set, so we pin the folio. This change assists with folio conversions, and makes the function more readable. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Vishal Moola (Oracle) <[email protected]> Cc: Matthew Wilcox (Oracle) <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent c9223a4 commit 503670e

File tree

1 file changed

+43
-43
lines changed

1 file changed

+43
-43
lines changed

mm/gup.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -124,58 +124,58 @@ static inline struct folio *try_get_folio(struct page *page, int refs)
124124
*/
125125
struct folio *try_grab_folio(struct page *page, int refs, unsigned int flags)
126126
{
127+
struct folio *folio;
128+
129+
if (WARN_ON_ONCE((flags & (FOLL_GET | FOLL_PIN)) == 0))
130+
return NULL;
131+
127132
if (unlikely(!(flags & FOLL_PCI_P2PDMA) && is_pci_p2pdma_page(page)))
128133
return NULL;
129134

130-
if (flags & FOLL_GET)
131-
return try_get_folio(page, refs);
132-
else if (flags & FOLL_PIN) {
133-
struct folio *folio;
135+
folio = try_get_folio(page, refs);
134136

135-
/*
136-
* Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a
137-
* right zone, so fail and let the caller fall back to the slow
138-
* path.
139-
*/
140-
if (unlikely((flags & FOLL_LONGTERM) &&
141-
!is_longterm_pinnable_page(page)))
142-
return NULL;
137+
if (flags & FOLL_GET)
138+
return folio;
143139

144-
/*
145-
* CAUTION: Don't use compound_head() on the page before this
146-
* point, the result won't be stable.
147-
*/
148-
folio = try_get_folio(page, refs);
149-
if (!folio)
150-
return NULL;
140+
/* FOLL_PIN is set */
141+
if (!folio)
142+
return NULL;
151143

152-
/*
153-
* When pinning a large folio, use an exact count to track it.
154-
*
155-
* However, be sure to *also* increment the normal folio
156-
* refcount field at least once, so that the folio really
157-
* is pinned. That's why the refcount from the earlier
158-
* try_get_folio() is left intact.
159-
*/
160-
if (folio_test_large(folio))
161-
atomic_add(refs, &folio->_pincount);
162-
else
163-
folio_ref_add(folio,
164-
refs * (GUP_PIN_COUNTING_BIAS - 1));
165-
/*
166-
* Adjust the pincount before re-checking the PTE for changes.
167-
* This is essentially a smp_mb() and is paired with a memory
168-
* barrier in page_try_share_anon_rmap().
169-
*/
170-
smp_mb__after_atomic();
144+
/*
145+
* Can't do FOLL_LONGTERM + FOLL_PIN gup fast path if not in a
146+
* right zone, so fail and let the caller fall back to the slow
147+
* path.
148+
*/
149+
if (unlikely((flags & FOLL_LONGTERM) &&
150+
!folio_is_longterm_pinnable(folio))) {
151+
if (!put_devmap_managed_page_refs(&folio->page, refs))
152+
folio_put_refs(folio, refs);
153+
return NULL;
154+
}
171155

172-
node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, refs);
156+
/*
157+
* When pinning a large folio, use an exact count to track it.
158+
*
159+
* However, be sure to *also* increment the normal folio
160+
* refcount field at least once, so that the folio really
161+
* is pinned. That's why the refcount from the earlier
162+
* try_get_folio() is left intact.
163+
*/
164+
if (folio_test_large(folio))
165+
atomic_add(refs, &folio->_pincount);
166+
else
167+
folio_ref_add(folio,
168+
refs * (GUP_PIN_COUNTING_BIAS - 1));
169+
/*
170+
* Adjust the pincount before re-checking the PTE for changes.
171+
* This is essentially a smp_mb() and is paired with a memory
172+
* barrier in page_try_share_anon_rmap().
173+
*/
174+
smp_mb__after_atomic();
173175

174-
return folio;
175-
}
176+
node_stat_mod_folio(folio, NR_FOLL_PIN_ACQUIRED, refs);
176177

177-
WARN_ON_ONCE(1);
178-
return NULL;
178+
return folio;
179179
}
180180

181181
static void gup_put_folio(struct folio *folio, int refs, unsigned int flags)

0 commit comments

Comments
 (0)