mm: Provide a function to get an additional pin on a page
Provide a function to get an additional pin on a page that we already have a pin on. This will be used in fs/direct-io.c when dispatching multiple bios to a page we've extracted from a user-backed iter rather than redoing the extraction. Signed-off-by: David Howells <dhowells@redhat.com> cc: Christoph Hellwig <hch@infradead.org> cc: David Hildenbrand <david@redhat.com> cc: Lorenzo Stoakes <lstoakes@gmail.com> cc: Andrew Morton <akpm@linux-foundation.org> cc: Jens Axboe <axboe@kernel.dk> cc: Al Viro <viro@zeniv.linux.org.uk> cc: Matthew Wilcox <willy@infradead.org> cc: Jan Kara <jack@suse.cz> cc: Jeff Layton <jlayton@kernel.org> cc: Jason Gunthorpe <jgg@nvidia.com> cc: Logan Gunthorpe <logang@deltatee.com> cc: Hillf Danton <hdanton@sina.com> cc: Christian Brauner <brauner@kernel.org> cc: Linus Torvalds <torvalds@linux-foundation.org> cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org cc: linux-kernel@vger.kernel.org cc: linux-mm@kvack.org Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: David Hildenbrand <david@redhat.com> Link: https://lore.kernel.org/r/20230526214142.958751-3-dhowells@redhat.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
c8070b7875
commit
1101fb8f89
@ -2405,6 +2405,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages,
|
||||
unsigned int gup_flags, struct page **pages);
|
||||
int pin_user_pages_fast(unsigned long start, int nr_pages,
|
||||
unsigned int gup_flags, struct page **pages);
|
||||
void folio_add_pin(struct folio *folio);
|
||||
|
||||
int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc);
|
||||
int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc,
|
||||
|
27
mm/gup.c
27
mm/gup.c
@ -275,6 +275,33 @@ void unpin_user_page(struct page *page)
|
||||
}
|
||||
EXPORT_SYMBOL(unpin_user_page);
|
||||
|
||||
/**
|
||||
* folio_add_pin - Try to get an additional pin on a pinned folio
|
||||
* @folio: The folio to be pinned
|
||||
*
|
||||
* Get an additional pin on a folio we already have a pin on. Makes no change
|
||||
* if the folio is a zero_page.
|
||||
*/
|
||||
void folio_add_pin(struct folio *folio)
|
||||
{
|
||||
if (is_zero_folio(folio))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Similar to try_grab_folio(): be sure to *also* increment the normal
|
||||
* page refcount field at least once, so that the page really is
|
||||
* pinned.
|
||||
*/
|
||||
if (folio_test_large(folio)) {
|
||||
WARN_ON_ONCE(atomic_read(&folio->_pincount) < 1);
|
||||
folio_ref_inc(folio);
|
||||
atomic_inc(&folio->_pincount);
|
||||
} else {
|
||||
WARN_ON_ONCE(folio_ref_count(folio) < GUP_PIN_COUNTING_BIAS);
|
||||
folio_ref_add(folio, GUP_PIN_COUNTING_BIAS);
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct folio *gup_folio_range_next(struct page *start,
|
||||
unsigned long npages, unsigned long i, unsigned int *ntails)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user