Message ID | 20230525223953.225496-3-dhowells@redhat.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | block: Make old dio use iov_iter_extract_pages() and page pinning | expand |
On Thu, May 25, 2023 at 3:40 PM David Howells <dhowells@redhat.com> wrote: > > +void page_get_additional_pin(struct page *page) > +{ > + struct folio *folio = page_folio(page); > + > + if (page == ZERO_PAGE(0)) > + return; You added that nice "is_zero_folio()", and then you did the above anyway.. Linus
Linus Torvalds <torvalds@linux-foundation.org> wrote: > > + if (page == ZERO_PAGE(0)) > > + return; > > You added that nice "is_zero_folio()", and then you did the above anyway.. Bah. Missed it because it was in a different patch. David
On Thu, May 25, 2023 at 11:39:52PM +0100, David Howells wrote: > +/** > + * page_get_additional_pin - Try to get an additional pin on a pinned page > + * @page: The page to be pinned > + * > + * Get an additional pin on a page we already have a pin on. Makes no change > + * if the page is the zero_page. > + */ > +void page_get_additional_pin(struct page *page) page_get_additional_pin seems like an odd name, mixing the get and pin terminologies. What about repin_page? Or move to a folio interface from the start can call it folio_repin?
Christoph Hellwig <hch@infradead.org> wrote: > > +void page_get_additional_pin(struct page *page) > > page_get_additional_pin seems like an odd name, mixing the get and > pin terminologies. What about repin_page? I considered that, though repin_page() suggests putting a pin back in after one is removed, but I can go with that if no one objects. > Or move to a folio interface from the start can call it folio_repin? I also considered this, but the entire gup interface is page-based at the moment, but I can do that too:-/ David
diff --git a/include/linux/mm.h b/include/linux/mm.h index 27ce77080c79..931b75dae7ff 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2383,6 +2383,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 page_get_additional_pin(struct page *page); 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, diff --git a/mm/gup.c b/mm/gup.c index 69b002628f5d..4b4353a184ed 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -275,6 +275,35 @@ void unpin_user_page(struct page *page) } EXPORT_SYMBOL(unpin_user_page); +/** + * page_get_additional_pin - Try to get an additional pin on a pinned page + * @page: The page to be pinned + * + * Get an additional pin on a page we already have a pin on. Makes no change + * if the page is the zero_page. + */ +void page_get_additional_pin(struct page *page) +{ + struct folio *folio = page_folio(page); + + if (page == ZERO_PAGE(0)) + 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_add(folio, 1); + atomic_add(1, &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) {
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: 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 --- include/linux/mm.h | 1 + mm/gup.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+)