[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230526214142.958751-3-dhowells@redhat.com>
Date: Fri, 26 May 2023 22:41:41 +0100
From: David Howells <dhowells@...hat.com>
To: Christoph Hellwig <hch@...radead.org>,
David Hildenbrand <david@...hat.com>,
Lorenzo Stoakes <lstoakes@...il.com>
Cc: David Howells <dhowells@...hat.com>, Jens Axboe <axboe@...nel.dk>,
Al Viro <viro@...iv.linux.org.uk>,
Matthew Wilcox <willy@...radead.org>, Jan Kara <jack@...e.cz>,
Jeff Layton <jlayton@...nel.org>,
Jason Gunthorpe <jgg@...dia.com>,
Logan Gunthorpe <logang@...tatee.com>,
Hillf Danton <hdanton@...a.com>,
Christian Brauner <brauner@...nel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
linux-fsdevel@...r.kernel.org, linux-block@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-mm@...ck.org,
Andrew Morton <akpm@...ux-foundation.org>
Subject: [PATCH v4 2/3] 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@...hat.com>
cc: Christoph Hellwig <hch@...radead.org>
cc: David Hildenbrand <david@...hat.com>
cc: Lorenzo Stoakes <lstoakes@...il.com>
cc: Andrew Morton <akpm@...ux-foundation.org>
cc: Jens Axboe <axboe@...nel.dk>
cc: Al Viro <viro@...iv.linux.org.uk>
cc: Matthew Wilcox <willy@...radead.org>
cc: Jan Kara <jack@...e.cz>
cc: Jeff Layton <jlayton@...nel.org>
cc: Jason Gunthorpe <jgg@...dia.com>
cc: Logan Gunthorpe <logang@...tatee.com>
cc: Hillf Danton <hdanton@...a.com>
cc: Christian Brauner <brauner@...nel.org>
cc: Linus Torvalds <torvalds@...ux-foundation.org>
cc: linux-fsdevel@...r.kernel.org
cc: linux-block@...r.kernel.org
cc: linux-kernel@...r.kernel.org
cc: linux-mm@...ck.org
---
Notes:
ver #4)
- Use _inc rather than _add ops when we're just adding 1.
ver #3)
- Rename to folio_add_pin().
- Change to using is_zero_folio()
include/linux/mm.h | 1 +
mm/gup.c | 27 +++++++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 3c2f6b452586..200068d98686 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -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,
diff --git a/mm/gup.c b/mm/gup.c
index ad28261dcafd..0814576b7366 100644
--- a/mm/gup.c
+++ b/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)
{
Powered by blists - more mailing lists