From: Andrew Morton <akpm@linux-foundation.org>
To: corbet@lwn.net, dan.j.williams@intel.com, david@fromorbit.com,
hch@infradead.org, ira.weiny@intel.com, jack@suse.cz,
jgg@ziepe.ca, jglisse@redhat.com, jhubbard@nvidia.com,
kirill.shutemov@linux.intel.com, mhocko@suse.com,
mike.kravetz@oracle.com, mm-commits@vger.kernel.org,
shuah@kernel.org, vbabka@suse.cz, viro@zeniv.linux.org.uk,
willy@infradead.org
Subject: + mm-gup-track-foll_pin-pages.patch added to -mm tree
Date: Mon, 10 Feb 2020 21:50:41 -0800 [thread overview]
Message-ID: <20200211055041.F8LyqvT8s%akpm@linux-foundation.org> (raw)
In-Reply-To: <20200203173311.6269a8be06a05e5a4aa08a93@linux-foundation.org>
The patch titled
Subject: mm/gup: track FOLL_PIN pages
has been added to the -mm tree. Its filename is
mm-gup-track-foll_pin-pages.patch
This patch should soon appear at
http://ozlabs.org/~akpm/mmots/broken-out/mm-gup-track-foll_pin-pages.patch
and later at
http://ozlabs.org/~akpm/mmotm/broken-out/mm-gup-track-foll_pin-pages.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: John Hubbard <jhubbard@nvidia.com>
Subject: mm/gup: track FOLL_PIN pages
Add tracking of pages that were pinned via FOLL_PIN. This tracking is
implemented via overloading of page->_refcount: pins are added by adding
GUP_PIN_COUNTING_BIAS (1024) to the refcount. This provides a fuzzy
indication of pinning, and it can have false positives (and that's OK).
Please see the pre-existing Documentation/core-api/pin_user_pages.rst for
details.
As mentioned in pin_user_pages.rst, callers who effectively set FOLL_PIN
(typically via pin_user_pages*()) are required to ultimately free such
pages via unpin_user_page().
Please also note the limitation, discussed in pin_user_pages.rst under the
"TODO: for 1GB and larger huge pages" section. (That limitation will be
removed in a following patch.)
The effect of a FOLL_PIN flag is similar to that of FOLL_GET, and may be
thought of as "FOLL_GET for DIO and/or RDMA use".
Pages that have been pinned via FOLL_PIN are identifiable via a new
function call:
bool page_maybe_dma_pinned(struct page *page);
What to do in response to encountering such a page, is left to later
patchsets. There is discussion about this in [1], [2], [3], and [4].
This also changes a BUG_ON(), to a WARN_ON(), in follow_page_mask().
[1] Some slow progress on get_user_pages() (Apr 2, 2019):
https://lwn.net/Articles/784574/
[2] DMA and get_user_pages() (LPC: Dec 12, 2018):
https://lwn.net/Articles/774411/
[3] The trouble with get_user_pages() (Apr 30, 2018):
https://lwn.net/Articles/753027/
[4] LWN kernel index: get_user_pages():
https://lwn.net/Kernel/Index/#Memory_management-get_user_pages
Link: http://lkml.kernel.org/r/20200211001536.1027652-7-jhubbard@nvidia.com
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Suggested-by: Jan Kara <jack@suse.cz>
Suggested-by: Jérôme Glisse <jglisse@redhat.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Chinner <david@fromorbit.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
Documentation/core-api/pin_user_pages.rst | 6
include/linux/mm.h | 84 +++++-
mm/gup.c | 254 ++++++++++++++++----
mm/huge_memory.c | 29 +-
mm/hugetlb.c | 54 ++--
5 files changed, 335 insertions(+), 92 deletions(-)
--- a/Documentation/core-api/pin_user_pages.rst~mm-gup-track-foll_pin-pages
+++ a/Documentation/core-api/pin_user_pages.rst
@@ -173,8 +173,8 @@ CASE 4: Pinning for struct page manipula
-------------------------------------------------
Here, normal GUP calls are sufficient, so neither flag needs to be set.
-page_dma_pinned(): the whole point of pinning
-=============================================
+page_maybe_dma_pinned(): the whole point of pinning
+===================================================
The whole point of marking pages as "DMA-pinned" or "gup-pinned" is to be able
to query, "is this page DMA-pinned?" That allows code such as page_mkclean()
@@ -186,7 +186,7 @@ and debates (see the References at the e
here: fill in the details once that's worked out. Meanwhile, it's safe to say
that having this available: ::
- static inline bool page_dma_pinned(struct page *page)
+ static inline bool page_maybe_dma_pinned(struct page *page)
...is a prerequisite to solving the long-running gup+DMA problem.
--- a/include/linux/mm.h~mm-gup-track-foll_pin-pages
+++ a/include/linux/mm.h
@@ -1001,6 +1001,8 @@ static inline void get_page(struct page
page_ref_inc(page);
}
+bool __must_check try_grab_page(struct page *page, unsigned int flags);
+
static inline __must_check bool try_get_page(struct page *page)
{
page = compound_head(page);
@@ -1029,29 +1031,79 @@ static inline void put_page(struct page
__put_page(page);
}
-/**
- * unpin_user_page() - release a gup-pinned page
- * @page: pointer to page to be released
+/*
+ * GUP_PIN_COUNTING_BIAS, and the associated functions that use it, overload
+ * the page's refcount so that two separate items are tracked: the original page
+ * reference count, and also a new count of how many pin_user_pages() calls were
+ * made against the page. ("gup-pinned" is another term for the latter).
+ *
+ * With this scheme, pin_user_pages() becomes special: such pages are marked as
+ * distinct from normal pages. As such, the unpin_user_page() call (and its
+ * variants) must be used in order to release gup-pinned pages.
+ *
+ * Choice of value:
+ *
+ * By making GUP_PIN_COUNTING_BIAS a power of two, debugging of page reference
+ * counts with respect to pin_user_pages() and unpin_user_page() becomes
+ * simpler, due to the fact that adding an even power of two to the page
+ * refcount has the effect of using only the upper N bits, for the code that
+ * counts up using the bias value. This means that the lower bits are left for
+ * the exclusive use of the original code that increments and decrements by one
+ * (or at least, by much smaller values than the bias value).
+ *
+ * Of course, once the lower bits overflow into the upper bits (and this is
+ * OK, because subtraction recovers the original values), then visual inspection
+ * no longer suffices to directly view the separate counts. However, for normal
+ * applications that don't have huge page reference counts, this won't be an
+ * issue.
*
- * Pages that were pinned via pin_user_pages*() must be released via either
- * unpin_user_page(), or one of the unpin_user_pages*() routines. This is so
- * that eventually such pages can be separately tracked and uniquely handled. In
- * particular, interactions with RDMA and filesystems need special handling.
- *
- * unpin_user_page() and put_page() are not interchangeable, despite this early
- * implementation that makes them look the same. unpin_user_page() calls must
- * be perfectly matched up with pin*() calls.
+ * Locking: the lockless algorithm described in page_cache_get_speculative()
+ * and page_cache_gup_pin_speculative() provides safe operation for
+ * get_user_pages and page_mkclean and other calls that race to set up page
+ * table entries.
*/
-static inline void unpin_user_page(struct page *page)
-{
- put_page(page);
-}
+#define GUP_PIN_COUNTING_BIAS (1U << 10)
+void unpin_user_page(struct page *page);
void unpin_user_pages_dirty_lock(struct page **pages, unsigned long npages,
bool make_dirty);
-
void unpin_user_pages(struct page **pages, unsigned long npages);
+/**
+ * page_maybe_dma_pinned() - report if a page is pinned for DMA.
+ *
+ * This function checks if a page has been pinned via a call to
+ * pin_user_pages*().
+ *
+ * For non-huge pages, the return value is partially fuzzy: false is not fuzzy,
+ * because it means "definitely not pinned for DMA", but true means "probably
+ * pinned for DMA, but possibly a false positive due to having at least
+ * GUP_PIN_COUNTING_BIAS worth of normal page references".
+ *
+ * False positives are OK, because: a) it's unlikely for a page to get that many
+ * refcounts, and b) all the callers of this routine are expected to be able to
+ * deal gracefully with a false positive.
+ *
+ * For more information, please see Documentation/vm/pin_user_pages.rst.
+ *
+ * @page: pointer to page to be queried.
+ * @Return: True, if it is likely that the page has been "dma-pinned".
+ * False, if the page is definitely not dma-pinned.
+ */
+static inline bool page_maybe_dma_pinned(struct page *page)
+{
+ /*
+ * page_ref_count() is signed. If that refcount overflows, then
+ * page_ref_count() returns a negative value, and callers will avoid
+ * further incrementing the refcount.
+ *
+ * Here, for that overflow case, use the signed bit to count a little
+ * bit higher via unsigned math, and thus still get an accurate result.
+ */
+ return ((unsigned int)page_ref_count(compound_head(page))) >=
+ GUP_PIN_COUNTING_BIAS;
+}
+
#if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP)
#define SECTION_IN_PAGE_FLAGS
#endif
--- a/mm/gup.c~mm-gup-track-foll_pin-pages
+++ a/mm/gup.c
@@ -44,6 +44,135 @@ static inline struct page *try_get_compo
return head;
}
+/*
+ * try_grab_compound_head() - attempt to elevate a page's refcount, by a
+ * flags-dependent amount.
+ *
+ * "grab" names in this file mean, "look at flags to decide whether to use
+ * FOLL_PIN or FOLL_GET behavior, when incrementing the page's refcount.
+ *
+ * Either FOLL_PIN or FOLL_GET (or neither) must be set, but not both at the
+ * same time. (That's true throughout the get_user_pages*() and
+ * pin_user_pages*() APIs.) Cases:
+ *
+ * FOLL_GET: page's refcount will be incremented by 1.
+ * FOLL_PIN: page's refcount will be incremented by GUP_PIN_COUNTING_BIAS.
+ *
+ * Return: head page (with refcount appropriately incremented) for success, or
+ * NULL upon failure. If neither FOLL_GET nor FOLL_PIN was set, that's
+ * considered failure, and furthermore, a likely bug in the caller, so a warning
+ * is also emitted.
+ */
+static __maybe_unused struct page *try_grab_compound_head(struct page *page,
+ int refs,
+ unsigned int flags)
+{
+ if (flags & FOLL_GET)
+ return try_get_compound_head(page, refs);
+ else if (flags & FOLL_PIN) {
+ refs *= GUP_PIN_COUNTING_BIAS;
+ return try_get_compound_head(page, refs);
+ }
+
+ WARN_ON_ONCE(1);
+ return NULL;
+}
+
+/**
+ * try_grab_page() - elevate a page's refcount by a flag-dependent amount
+ *
+ * This might not do anything at all, depending on the flags argument.
+ *
+ * "grab" names in this file mean, "look at flags to decide whether to use
+ * FOLL_PIN or FOLL_GET behavior, when incrementing the page's refcount.
+ *
+ * @page: pointer to page to be grabbed
+ * @flags: gup flags: these are the FOLL_* flag values.
+ *
+ * Either FOLL_PIN or FOLL_GET (or neither) may be set, but not both at the same
+ * time. Cases:
+ *
+ * FOLL_GET: page's refcount will be incremented by 1.
+ * FOLL_PIN: page's refcount will be incremented by GUP_PIN_COUNTING_BIAS.
+ *
+ * Return: true for success, or if no action was required (if neither FOLL_PIN
+ * nor FOLL_GET was set, nothing is done). False for failure: FOLL_GET or
+ * FOLL_PIN was set, but the page could not be grabbed.
+ */
+bool __must_check try_grab_page(struct page *page, unsigned int flags)
+{
+ WARN_ON_ONCE((flags & (FOLL_GET | FOLL_PIN)) == (FOLL_GET | FOLL_PIN));
+
+ if (flags & FOLL_GET)
+ return try_get_page(page);
+ else if (flags & FOLL_PIN) {
+ page = compound_head(page);
+
+ if (WARN_ON_ONCE(page_ref_count(page) <= 0))
+ return false;
+
+ page_ref_add(page, GUP_PIN_COUNTING_BIAS);
+ }
+
+ return true;
+}
+
+#ifdef CONFIG_DEV_PAGEMAP_OPS
+static bool __unpin_devmap_managed_user_page(struct page *page)
+{
+ int count;
+
+ if (!page_is_devmap_managed(page))
+ return false;
+
+ count = page_ref_sub_return(page, GUP_PIN_COUNTING_BIAS);
+
+ /*
+ * devmap page refcounts are 1-based, rather than 0-based: if
+ * refcount is 1, then the page is free and the refcount is
+ * stable because nobody holds a reference on the page.
+ */
+ if (count == 1)
+ free_devmap_managed_page(page);
+ else if (!count)
+ __put_page(page);
+
+ return true;
+}
+#else
+static bool __unpin_devmap_managed_user_page(struct page *page)
+{
+ return false;
+}
+#endif /* CONFIG_DEV_PAGEMAP_OPS */
+
+/**
+ * unpin_user_page() - release a dma-pinned page
+ * @page: pointer to page to be released
+ *
+ * Pages that were pinned via pin_user_pages*() must be released via either
+ * unpin_user_page(), or one of the unpin_user_pages*() routines. This is so
+ * that such pages can be separately tracked and uniquely handled. In
+ * particular, interactions with RDMA and filesystems need special handling.
+ */
+void unpin_user_page(struct page *page)
+{
+ page = compound_head(page);
+
+ /*
+ * For devmap managed pages we need to catch refcount transition from
+ * GUP_PIN_COUNTING_BIAS to 1, when refcount reach one it means the
+ * page is free and we need to inform the device driver through
+ * callback. See include/linux/memremap.h and HMM for details.
+ */
+ if (__unpin_devmap_managed_user_page(page))
+ return;
+
+ if (page_ref_sub_and_test(page, GUP_PIN_COUNTING_BIAS))
+ __put_page(page);
+}
+EXPORT_SYMBOL(unpin_user_page);
+
/**
* unpin_user_pages_dirty_lock() - release and optionally dirty gup-pinned pages
* @pages: array of pages to be maybe marked dirty, and definitely released.
@@ -230,10 +359,11 @@ retry:
}
page = vm_normal_page(vma, address, pte);
- if (!page && pte_devmap(pte) && (flags & FOLL_GET)) {
+ if (!page && pte_devmap(pte) && (flags & (FOLL_GET | FOLL_PIN))) {
/*
- * Only return device mapping pages in the FOLL_GET case since
- * they are only valid while holding the pgmap reference.
+ * Only return device mapping pages in the FOLL_GET or FOLL_PIN
+ * case since they are only valid while holding the pgmap
+ * reference.
*/
*pgmap = get_dev_pagemap(pte_pfn(pte), *pgmap);
if (*pgmap)
@@ -271,11 +401,10 @@ retry:
goto retry;
}
- if (flags & FOLL_GET) {
- if (unlikely(!try_get_page(page))) {
- page = ERR_PTR(-ENOMEM);
- goto out;
- }
+ /* try_grab_page() does nothing unless FOLL_GET or FOLL_PIN is set. */
+ if (unlikely(!try_grab_page(page, flags))) {
+ page = ERR_PTR(-ENOMEM);
+ goto out;
}
if (flags & FOLL_TOUCH) {
if ((flags & FOLL_WRITE) &&
@@ -537,7 +666,7 @@ static struct page *follow_page_mask(str
/* make this handle hugepd */
page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
if (!IS_ERR(page)) {
- BUG_ON(flags & FOLL_GET);
+ WARN_ON_ONCE(flags & (FOLL_GET | FOLL_PIN));
return page;
}
@@ -1675,6 +1804,15 @@ long get_user_pages_remote(struct task_s
{
return 0;
}
+
+static long __get_user_pages_remote(struct task_struct *tsk,
+ struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas, int *locked)
+{
+ return 0;
+}
#endif /* !CONFIG_MMU */
/*
@@ -1877,7 +2015,10 @@ static void __maybe_unused undo_dev_page
struct page *page = pages[--(*nr)];
ClearPageReferenced(page);
- put_page(page);
+ if (flags & FOLL_PIN)
+ unpin_user_page(page);
+ else
+ put_page(page);
}
}
@@ -1919,7 +2060,7 @@ static int gup_pte_range(pmd_t pmd, unsi
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
page = pte_page(pte);
- head = try_get_compound_head(page, 1);
+ head = try_grab_compound_head(page, 1, flags);
if (!head)
goto pte_unmap;
@@ -1980,7 +2121,10 @@ static int __gup_device_huge(unsigned lo
}
SetPageReferenced(page);
pages[*nr] = page;
- get_page(page);
+ if (unlikely(!try_grab_page(page, flags))) {
+ undo_dev_pagemap(nr, nr_start, flags, pages);
+ return 0;
+ }
(*nr)++;
pfn++;
} while (addr += PAGE_SIZE, addr != end);
@@ -2056,6 +2200,9 @@ static int record_subpages(struct page *
static void put_compound_head(struct page *page, int refs, unsigned int flags)
{
+ if (flags & FOLL_PIN)
+ refs *= GUP_PIN_COUNTING_BIAS;
+
VM_BUG_ON_PAGE(page_ref_count(page) < refs, page);
/*
* Calling put_page() for each ref is unnecessarily slow. Only the last
@@ -2099,7 +2246,7 @@ static int gup_hugepte(pte_t *ptep, unsi
page = head + ((addr & (sz-1)) >> PAGE_SHIFT);
refs = record_subpages(page, addr, end, pages + *nr);
- head = try_get_compound_head(head, refs);
+ head = try_grab_compound_head(head, refs, flags);
if (!head)
return 0;
@@ -2159,7 +2306,7 @@ static int gup_huge_pmd(pmd_t orig, pmd_
page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
refs = record_subpages(page, addr, end, pages + *nr);
- head = try_get_compound_head(pmd_page(orig), refs);
+ head = try_grab_compound_head(pmd_page(orig), refs, flags);
if (!head)
return 0;
@@ -2193,7 +2340,7 @@ static int gup_huge_pud(pud_t orig, pud_
page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
refs = record_subpages(page, addr, end, pages + *nr);
- head = try_get_compound_head(pud_page(orig), refs);
+ head = try_grab_compound_head(pud_page(orig), refs, flags);
if (!head)
return 0;
@@ -2222,7 +2369,7 @@ static int gup_huge_pgd(pgd_t orig, pgd_
page = pgd_page(orig) + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT);
refs = record_subpages(page, addr, end, pages + *nr);
- head = try_get_compound_head(pgd_page(orig), refs);
+ head = try_grab_compound_head(pgd_page(orig), refs, flags);
if (!head)
return 0;
@@ -2505,11 +2652,11 @@ static int internal_get_user_pages_fast(
/**
* get_user_pages_fast() - pin user pages in memory
- * @start: starting user address
- * @nr_pages: number of pages from start to pin
- * @gup_flags: flags modifying pin behaviour
- * @pages: array that receives pointers to the pages pinned.
- * Should be at least nr_pages long.
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @gup_flags: flags modifying pin behaviour
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
*
* Attempt to pin user pages in memory without taking mm->mmap_sem.
* If not successful, it will fall back to taking the lock and
@@ -2543,9 +2690,12 @@ EXPORT_SYMBOL_GPL(get_user_pages_fast);
/**
* pin_user_pages_fast() - pin user pages in memory without taking locks
*
- * For now, this is a placeholder function, until various call sites are
- * converted to use the correct get_user_pages*() or pin_user_pages*() API. So,
- * this is identical to get_user_pages_fast().
+ * Nearly the same as get_user_pages_fast(), except that FOLL_PIN is set. See
+ * get_user_pages_fast() for documentation on the function arguments, because
+ * the arguments here are identical.
+ *
+ * FOLL_PIN means that the pages must be released via unpin_user_page(). Please
+ * see Documentation/vm/pin_user_pages.rst for further details.
*
* This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It
* is NOT intended for Case 2 (RDMA: long-term pins).
@@ -2553,21 +2703,24 @@ EXPORT_SYMBOL_GPL(get_user_pages_fast);
int pin_user_pages_fast(unsigned long start, int nr_pages,
unsigned int gup_flags, struct page **pages)
{
- /*
- * This is a placeholder, until the pin functionality is activated.
- * Until then, just behave like the corresponding get_user_pages*()
- * routine.
- */
- return get_user_pages_fast(start, nr_pages, gup_flags, pages);
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE(gup_flags & FOLL_GET))
+ return -EINVAL;
+
+ gup_flags |= FOLL_PIN;
+ return internal_get_user_pages_fast(start, nr_pages, gup_flags, pages);
}
EXPORT_SYMBOL_GPL(pin_user_pages_fast);
/**
* pin_user_pages_remote() - pin pages of a remote process (task != current)
*
- * For now, this is a placeholder function, until various call sites are
- * converted to use the correct get_user_pages*() or pin_user_pages*() API. So,
- * this is identical to get_user_pages_remote().
+ * Nearly the same as get_user_pages_remote(), except that FOLL_PIN is set. See
+ * get_user_pages_remote() for documentation on the function arguments, because
+ * the arguments here are identical.
+ *
+ * FOLL_PIN means that the pages must be released via unpin_user_page(). Please
+ * see Documentation/vm/pin_user_pages.rst for details.
*
* This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It
* is NOT intended for Case 2 (RDMA: long-term pins).
@@ -2577,22 +2730,24 @@ long pin_user_pages_remote(struct task_s
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas, int *locked)
{
- /*
- * This is a placeholder, until the pin functionality is activated.
- * Until then, just behave like the corresponding get_user_pages*()
- * routine.
- */
- return get_user_pages_remote(tsk, mm, start, nr_pages, gup_flags, pages,
- vmas, locked);
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE(gup_flags & FOLL_GET))
+ return -EINVAL;
+
+ gup_flags |= FOLL_PIN;
+ return __get_user_pages_remote(tsk, mm, start, nr_pages, gup_flags,
+ pages, vmas, locked);
}
EXPORT_SYMBOL(pin_user_pages_remote);
/**
* pin_user_pages() - pin user pages in memory for use by other devices
*
- * For now, this is a placeholder function, until various call sites are
- * converted to use the correct get_user_pages*() or pin_user_pages*() API. So,
- * this is identical to get_user_pages().
+ * Nearly the same as get_user_pages(), except that FOLL_TOUCH is not set, and
+ * FOLL_PIN is set.
+ *
+ * FOLL_PIN means that the pages must be released via unpin_user_page(). Please
+ * see Documentation/vm/pin_user_pages.rst for details.
*
* This is intended for Case 1 (DIO) in Documentation/vm/pin_user_pages.rst. It
* is NOT intended for Case 2 (RDMA: long-term pins).
@@ -2601,11 +2756,12 @@ long pin_user_pages(unsigned long start,
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas)
{
- /*
- * This is a placeholder, until the pin functionality is activated.
- * Until then, just behave like the corresponding get_user_pages*()
- * routine.
- */
- return get_user_pages(start, nr_pages, gup_flags, pages, vmas);
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE(gup_flags & FOLL_GET))
+ return -EINVAL;
+
+ gup_flags |= FOLL_PIN;
+ return __gup_longterm_locked(current, current->mm, start, nr_pages,
+ pages, vmas, gup_flags);
}
EXPORT_SYMBOL(pin_user_pages);
--- a/mm/huge_memory.c~mm-gup-track-foll_pin-pages
+++ a/mm/huge_memory.c
@@ -958,6 +958,11 @@ struct page *follow_devmap_pmd(struct vm
*/
WARN_ONCE(flags & FOLL_COW, "mm: In follow_devmap_pmd with FOLL_COW set");
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ (FOLL_PIN | FOLL_GET)))
+ return NULL;
+
if (flags & FOLL_WRITE && !pmd_write(*pmd))
return NULL;
@@ -973,7 +978,7 @@ struct page *follow_devmap_pmd(struct vm
* device mapped pages can only be returned if the
* caller will manage the page reference count.
*/
- if (!(flags & FOLL_GET))
+ if (!(flags & (FOLL_GET | FOLL_PIN)))
return ERR_PTR(-EEXIST);
pfn += (addr & ~PMD_MASK) >> PAGE_SHIFT;
@@ -981,7 +986,8 @@ struct page *follow_devmap_pmd(struct vm
if (!*pgmap)
return ERR_PTR(-EFAULT);
page = pfn_to_page(pfn);
- get_page(page);
+ if (!try_grab_page(page, flags))
+ page = ERR_PTR(-ENOMEM);
return page;
}
@@ -1101,6 +1107,11 @@ struct page *follow_devmap_pud(struct vm
if (flags & FOLL_WRITE && !pud_write(*pud))
return NULL;
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ (FOLL_PIN | FOLL_GET)))
+ return NULL;
+
if (pud_present(*pud) && pud_devmap(*pud))
/* pass */;
else
@@ -1112,8 +1123,10 @@ struct page *follow_devmap_pud(struct vm
/*
* device mapped pages can only be returned if the
* caller will manage the page reference count.
+ *
+ * At least one of FOLL_GET | FOLL_PIN must be set, so assert that here:
*/
- if (!(flags & FOLL_GET))
+ if (!(flags & (FOLL_GET | FOLL_PIN)))
return ERR_PTR(-EEXIST);
pfn += (addr & ~PUD_MASK) >> PAGE_SHIFT;
@@ -1121,7 +1134,8 @@ struct page *follow_devmap_pud(struct vm
if (!*pgmap)
return ERR_PTR(-EFAULT);
page = pfn_to_page(pfn);
- get_page(page);
+ if (!try_grab_page(page, flags))
+ page = ERR_PTR(-ENOMEM);
return page;
}
@@ -1497,8 +1511,13 @@ struct page *follow_trans_huge_pmd(struc
page = pmd_page(*pmd);
VM_BUG_ON_PAGE(!PageHead(page) && !is_zone_device_page(page), page);
+
+ if (!try_grab_page(page, flags))
+ return ERR_PTR(-ENOMEM);
+
if (flags & FOLL_TOUCH)
touch_pmd(vma, addr, pmd, flags);
+
if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
/*
* We don't mlock() pte-mapped THPs. This way we can avoid
@@ -1535,8 +1554,6 @@ struct page *follow_trans_huge_pmd(struc
skip_mlock:
page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT;
VM_BUG_ON_PAGE(!PageCompound(page) && !is_zone_device_page(page), page);
- if (flags & FOLL_GET)
- get_page(page);
out:
return page;
--- a/mm/hugetlb.c~mm-gup-track-foll_pin-pages
+++ a/mm/hugetlb.c
@@ -4376,19 +4376,6 @@ long follow_hugetlb_page(struct mm_struc
page = pte_page(huge_ptep_get(pte));
/*
- * Instead of doing 'try_get_page()' below in the same_page
- * loop, just check the count once here.
- */
- if (unlikely(page_count(page) <= 0)) {
- if (pages) {
- spin_unlock(ptl);
- remainder = 0;
- err = -ENOMEM;
- break;
- }
- }
-
- /*
* If subpage information not requested, update counters
* and skip the same_page loop below.
*/
@@ -4405,7 +4392,22 @@ long follow_hugetlb_page(struct mm_struc
same_page:
if (pages) {
pages[i] = mem_map_offset(page, pfn_offset);
- get_page(pages[i]);
+ /*
+ * try_grab_page() should always succeed here, because:
+ * a) we hold the ptl lock, and b) we've just checked
+ * that the huge page is present in the page tables. If
+ * the huge page is present, then the tail pages must
+ * also be present. The ptl prevents the head page and
+ * tail pages from being rearranged in any way. So this
+ * page must be available at this point, unless the page
+ * refcount overflowed:
+ */
+ if (WARN_ON_ONCE(!try_grab_page(pages[i], flags))) {
+ spin_unlock(ptl);
+ remainder = 0;
+ err = -ENOMEM;
+ break;
+ }
}
if (vmas)
@@ -4965,6 +4967,12 @@ follow_huge_pmd(struct mm_struct *mm, un
struct page *page = NULL;
spinlock_t *ptl;
pte_t pte;
+
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ (FOLL_PIN | FOLL_GET)))
+ return NULL;
+
retry:
ptl = pmd_lockptr(mm, pmd);
spin_lock(ptl);
@@ -4977,8 +4985,18 @@ retry:
pte = huge_ptep_get((pte_t *)pmd);
if (pte_present(pte)) {
page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
- if (flags & FOLL_GET)
- get_page(page);
+ /*
+ * try_grab_page() should always succeed here, because: a) we
+ * hold the pmd (ptl) lock, and b) we've just checked that the
+ * huge pmd (head) page is present in the page tables. The ptl
+ * prevents the head page and tail pages from being rearranged
+ * in any way. So this page must be available at this point,
+ * unless the page refcount overflowed:
+ */
+ if (WARN_ON_ONCE(!try_grab_page(page, flags))) {
+ page = NULL;
+ goto out;
+ }
} else {
if (is_hugetlb_entry_migration(pte)) {
spin_unlock(ptl);
@@ -4999,7 +5017,7 @@ struct page * __weak
follow_huge_pud(struct mm_struct *mm, unsigned long address,
pud_t *pud, int flags)
{
- if (flags & FOLL_GET)
+ if (flags & (FOLL_GET | FOLL_PIN))
return NULL;
return pte_page(*(pte_t *)pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT);
@@ -5008,7 +5026,7 @@ follow_huge_pud(struct mm_struct *mm, un
struct page * __weak
follow_huge_pgd(struct mm_struct *mm, unsigned long address, pgd_t *pgd, int flags)
{
- if (flags & FOLL_GET)
+ if (flags & (FOLL_GET | FOLL_PIN))
return NULL;
return pte_page(*(pte_t *)pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
_
Patches currently in -mm which might be from jhubbard@nvidia.com are
mm-gup-split-get_user_pages_remote-into-two-routines.patch
mm-gup-pass-a-flags-arg-to-__gup_device_-functions.patch
mm-introduce-page_ref_sub_return.patch
mm-gup-pass-gup-flags-to-two-more-routines.patch
mm-gup-require-foll_get-for-get_user_pages_fast.patch
mm-gup-track-foll_pin-pages.patch
mm-gup-page-hpage_pinned_refcount-exact-pin-counts-for-huge-pages.patch
mm-gup-proc-vmstat-pin_user_pages-foll_pin-reporting.patch
mm-gup_benchmark-support-pin_user_pages-and-related-calls.patch
selftests-vm-run_vmtests-invoke-gup_benchmark-with-basic-foll_pin-coverage.patch
mm-dump_page-additional-diagnostics-for-huge-pinned-pages.patch
next prev parent reply other threads:[~2020-02-11 5:50 UTC|newest]
Thread overview: 244+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-04 1:33 incoming Andrew Morton
2020-02-04 1:33 ` [patch 01/67] ocfs2: fix oops when writing cloned file Andrew Morton
2020-02-04 1:33 ` [patch 02/67] mm/page_alloc.c: fix uninitialized memmaps on a partially populated last section Andrew Morton
2020-02-04 1:33 ` [patch 03/67] fs/proc/page.c: allow inspection of last section and fix end detection Andrew Morton
2020-02-04 1:33 ` [patch 04/67] mm/page_alloc.c: initialize memmap of unavailable memory directly Andrew Morton
2020-02-04 1:33 ` [patch 05/67] mm/page_alloc: fix and rework pfn handling in memmap_init_zone() Andrew Morton
2020-02-04 1:34 ` [patch 06/67] mm: factor out next_present_section_nr() Andrew Morton
[not found] ` <CAHk-=widODg0oV6uNrpTvA3tFVN706o-nrWC5XBL9RZ4y3RFcg@mail.gmail.com>
2020-02-04 4:29 ` Andrew Morton
2020-02-04 1:34 ` [patch 07/67] mm/memmap_init: update variable name in memmap_init_zone Andrew Morton
2020-02-04 1:34 ` [patch 08/67] mm/memory_hotplug: poison memmap in remove_pfn_range_from_zone() Andrew Morton
2020-02-04 1:34 ` [patch 09/67] mm/memory_hotplug: we always have a zone in find_(smallest|biggest)_section_pfn Andrew Morton
2020-02-04 1:34 ` [patch 10/67] mm/memory_hotplug: don't check for "all holes" in shrink_zone_span() Andrew Morton
2020-02-04 1:34 ` [patch 11/67] mm/memory_hotplug: drop local variables " Andrew Morton
2020-02-04 1:34 ` [patch 12/67] mm/memory_hotplug: cleanup __remove_pages() Andrew Morton
2020-02-04 1:34 ` [patch 13/67] mm/memory_hotplug: drop valid_start/valid_end from test_pages_in_a_zone() Andrew Morton
2020-02-04 1:34 ` [patch 14/67] smp_mb__{before,after}_atomic(): update Documentation Andrew Morton
2020-02-04 1:34 ` [patch 15/67] ipc/mqueue.c: remove duplicated code Andrew Morton
2020-02-04 1:34 ` [patch 16/67] ipc/mqueue.c: update/document memory barriers Andrew Morton
2020-02-04 1:34 ` [patch 17/67] ipc/msg.c: update and document " Andrew Morton
2020-02-04 1:34 ` [patch 18/67] ipc/sem.c: document and update " Andrew Morton
2020-02-04 1:34 ` [patch 19/67] ipc/msg.c: consolidate all xxxctl_down() functions Andrew Morton
2020-02-04 1:34 ` [patch 20/67] drivers/block/null_blk_main.c: fix layout Andrew Morton
2020-02-04 1:34 ` [patch 21/67] drivers/block/null_blk_main.c: fix uninitialized var warnings Andrew Morton
2020-02-04 1:34 ` [patch 22/67] pinctrl: fix pxa2xx.c build warnings Andrew Morton
2020-02-04 1:34 ` [patch 23/67] mm: remove __krealloc Andrew Morton
2020-02-04 1:35 ` [patch 24/67] mm: add generic p?d_leaf() macros Andrew Morton
2020-02-04 1:35 ` [patch 25/67] arc: mm: add p?d_leaf() definitions Andrew Morton
2020-02-04 1:35 ` [patch 26/67] arm: " Andrew Morton
2020-02-04 1:35 ` [patch 27/67] arm64: " Andrew Morton
2020-02-04 1:35 ` [patch 28/67] mips: " Andrew Morton
2020-02-04 1:35 ` [patch 29/67] powerpc: " Andrew Morton
2020-02-04 1:35 ` [patch 30/67] riscv: " Andrew Morton
2020-02-04 1:35 ` [patch 31/67] s390: " Andrew Morton
2020-02-04 1:35 ` [patch 32/67] sparc: " Andrew Morton
2020-02-04 1:35 ` [patch 33/67] x86: " Andrew Morton
2020-02-04 1:35 ` [patch 34/67] mm: pagewalk: add p4d_entry() and pgd_entry() Andrew Morton
2020-02-04 1:35 ` [patch 35/67] mm: pagewalk: allow walking without vma Andrew Morton
2020-02-04 1:35 ` [patch 36/67] mm: pagewalk: don't lock PTEs for walk_page_range_novma() Andrew Morton
2020-02-04 1:35 ` [patch 37/67] mm: pagewalk: fix termination condition in walk_pte_range() Andrew Morton
2020-02-04 1:36 ` [patch 38/67] mm: pagewalk: add 'depth' parameter to pte_hole Andrew Morton
2020-02-04 1:36 ` [patch 39/67] x86: mm: point to struct seq_file from struct pg_state Andrew Morton
2020-02-04 1:36 ` [patch 40/67] x86: mm+efi: convert ptdump_walk_pgd_level() to take a mm_struct Andrew Morton
2020-02-04 1:36 ` [patch 41/67] x86: mm: convert ptdump_walk_pgd_level_debugfs() to take an mm_struct Andrew Morton
2020-02-04 1:36 ` [patch 42/67] mm: add generic ptdump Andrew Morton
2020-02-04 1:36 ` [patch 43/67] x86: mm: convert dump_pagetables to use walk_page_range Andrew Morton
2020-02-04 1:36 ` [patch 44/67] arm64: mm: convert mm/dump.c to use walk_page_range() Andrew Morton
2020-02-04 1:36 ` [patch 45/67] arm64: mm: display non-present entries in ptdump Andrew Morton
2020-02-04 1:36 ` [patch 46/67] mm: ptdump: reduce level numbers by 1 in note_page() Andrew Morton
2020-02-04 1:36 ` [patch 47/67] x86: mm: avoid allocating struct mm_struct on the stack Andrew Morton
2020-02-04 1:36 ` [patch 48/67] powerpc/mmu_gather: enable RCU_TABLE_FREE even for !SMP case Andrew Morton
2020-02-04 1:36 ` [patch 49/67] mm/mmu_gather: invalidate TLB correctly on batch allocation failure and flush Andrew Morton
2020-02-04 1:36 ` [patch 50/67] asm-generic/tlb: avoid potential double flush Andrew Morton
2020-02-04 1:36 ` [patch 51/67] asm-gemeric/tlb: remove stray function declarations Andrew Morton
2020-02-04 1:36 ` [patch 52/67] asm-generic/tlb: add missing CONFIG symbol Andrew Morton
2020-02-04 1:37 ` [patch 53/67] asm-generic/tlb: rename HAVE_RCU_TABLE_FREE Andrew Morton
2020-02-04 1:37 ` [patch 54/67] asm-generic/tlb: rename HAVE_MMU_GATHER_PAGE_SIZE Andrew Morton
2020-02-04 1:37 ` [patch 55/67] asm-generic/tlb: rename HAVE_MMU_GATHER_NO_GATHER Andrew Morton
2020-02-04 1:37 ` [patch 56/67] asm-generic/tlb: provide MMU_GATHER_TABLE_FREE Andrew Morton
2020-02-04 1:37 ` [patch 57/67] proc: decouple proc from VFS with "struct proc_ops" Andrew Morton
2020-02-04 1:37 ` [patch 58/67] proc: convert everything to " Andrew Morton
2020-02-04 1:37 ` [patch 59/67] lib/string: add strnchrnul() Andrew Morton
2020-02-04 1:37 ` [patch 60/67] bitops: more BITS_TO_* macros Andrew Morton
2020-02-04 1:37 ` [patch 61/67] lib: add test for bitmap_parse() Andrew Morton
2020-02-04 1:37 ` [patch 62/67] lib: make bitmap_parse_user a wrapper on bitmap_parse Andrew Morton
2020-02-04 1:37 ` [patch 63/67] lib: rework bitmap_parse() Andrew Morton
2020-02-04 1:37 ` [patch 64/67] lib: new testcases for bitmap_parse{_user} Andrew Morton
2020-02-04 1:37 ` [patch 65/67] include/linux/cpumask.h: don't calculate length of the input string Andrew Morton
2020-02-04 1:37 ` [patch 66/67] treewide: remove redundant IS_ERR() before error code check Andrew Morton
2020-02-04 1:37 ` [patch 67/67] ARM: dma-api: fix max_pfn off-by-one error in __dma_supported() Andrew Morton
2020-02-04 1:48 ` [merged] mips-kdb-remove-old-workaround-for-backtracing-on-other-cpus.patch removed from -mm tree Andrew Morton
2020-02-04 1:48 ` [merged] kdb-kdb_current_regs-should-be-private.patch " Andrew Morton
2020-02-04 1:48 ` [merged] kdb-kdb_current_task-shouldnt-be-exported.patch " Andrew Morton
2020-02-04 1:48 ` [merged] kdb-gid-rid-of-implicit-setting-of-the-current-task-regs.patch " Andrew Morton
2020-02-04 1:48 ` [merged] kdb-get-rid-of-confusing-diag-msg-from-rd-if-current-task-has-no-regs.patch " Andrew Morton
2020-02-04 1:49 ` [obsolete] linux-next-git-rejects.patch " Andrew Morton
[not found] ` <CAHk-=whog86e4fRY_sxHqAos6spwAi_4aFF49S7h5C4XAZM2qw@mail.gmail.com>
2020-02-04 2:46 ` incoming Andrew Morton
2020-02-10 0:55 ` + mm-dont-prepare-anon_vma-if-vma-has-vm_wipeonfork.patch added to -mm tree Andrew Morton
2020-02-10 0:55 ` + revert-mm-rmapc-reuse-mergeable-anon_vma-as-parent-when-fork.patch " Andrew Morton
2020-02-10 0:55 ` + mm-set-vm_next-and-vm_prev-to-null-in-vm_area_dup.patch " Andrew Morton
2020-02-10 1:03 ` + mm-list_lru-fix-a-data-race-in-list_lru_count_one.patch " Andrew Morton
2020-02-10 1:05 ` + mm-frontswap-mark-various-intentional-data-races.patch " Andrew Morton
2020-02-10 1:22 ` + mm-add-mremap_dontunmap-to-mremap.patch " Andrew Morton
2020-02-10 1:35 ` + mm-sparsemem-get-address-to-page-struct-instead-of-address-to-pfn.patch " Andrew Morton
2020-02-10 1:48 ` + mm-swapfile-fix-and-annotate-various-data-races.patch " Andrew Morton
2020-02-10 2:01 ` + mm-page_io-mark-various-intentional-data-races.patch " Andrew Morton
2020-02-10 2:01 ` + mm-swap_state-mark-various-intentional-data-races.patch " Andrew Morton
2020-02-10 4:00 ` + linux-pipe_fs_ih-fix-kernel-doc-warnings-after-wait-was-split.patch " Andrew Morton
2020-02-10 4:16 ` + mm-swap-move-inode_lock-out-of-claim_swapfile.patch " Andrew Morton
2020-02-10 4:20 ` + selftests-vm-add-missed-tests-in-run_vmtests.patch " Andrew Morton
2020-02-10 4:21 ` + mm-memcg-fix-build-error-around-the-usage-of-kmem_caches.patch " Andrew Morton
2020-02-10 4:23 ` + mm-memcontrol-fix-a-data-race-in-scan-count.patch " Andrew Morton
2020-02-10 4:29 ` + get_maintainer-remove-uses-of-p-for-maintainer-name.patch " Andrew Morton
2020-02-10 4:37 ` + scripts-get_maintainerpl-deprioritize-old-fixes-addresses.patch " Andrew Morton
2020-02-11 5:33 ` + mm-vmpressure-dont-need-call-kfree-if-kstrndup-fails.patch " Andrew Morton
2020-02-11 5:34 ` + mm-vmpressure-use-mem_cgroup_is_root-api.patch " Andrew Morton
2020-02-11 5:39 ` + mm-filemap-fix-a-data-race-in-filemap_fault.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup-split-get_user_pages_remote-into-two-routines.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup-pass-a-flags-arg-to-__gup_device_-functions.patch " Andrew Morton
2020-02-11 5:50 ` + mm-introduce-page_ref_sub_return.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup-pass-gup-flags-to-two-more-routines.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup-require-foll_get-for-get_user_pages_fast.patch " Andrew Morton
2020-02-11 5:50 ` Andrew Morton [this message]
2020-02-11 5:50 ` + mm-gup-page-hpage_pinned_refcount-exact-pin-counts-for-huge-pages.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup-proc-vmstat-pin_user_pages-foll_pin-reporting.patch " Andrew Morton
2020-02-11 5:50 ` + mm-gup_benchmark-support-pin_user_pages-and-related-calls.patch " Andrew Morton
2020-02-11 5:50 ` + selftests-vm-run_vmtests-invoke-gup_benchmark-with-basic-foll_pin-coverage.patch " Andrew Morton
2020-02-11 5:50 ` + mm-improve-dump_page-for-compound-pages.patch " Andrew Morton
2020-02-11 5:51 ` + mm-dump_page-additional-diagnostics-for-huge-pinned-pages.patch " Andrew Morton
2020-02-11 6:05 ` + mm-mapping_dirty_helpers-update-huge-page-table-entry-callbacks.patch " Andrew Morton
2020-02-11 6:06 ` + zswap-allow-setting-default-status-compressor-and-allocator-in-kconfig.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-hugetlb_cgroup-reservation-counter.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-interface-for-charge-uncharge-hugetlb-reservations.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-reservation-accounting-for-private-mappings.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb-disable-region_add-file_region-coalescing.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-accounting-for-shared-mappings.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-support-noreserve-mappings.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb-support-file_region-coalescing-again.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-hugetlb_cgroup-reservation-tests.patch " Andrew Morton
2020-02-11 23:19 ` + hugetlb_cgroup-add-hugetlb_cgroup-reservation-docs.patch " Andrew Morton
2020-02-11 23:21 ` + lib-bch-replace-zero-length-array-with-flexible-array-member.patch " Andrew Morton
2020-02-11 23:21 ` + lib-objagg-replace-zero-length-arrays-with-flexible-array-member.patch " Andrew Morton
2020-02-11 23:21 ` + lib-ts_bm-replace-zero-length-array-with-flexible-array-member.patch " Andrew Morton
2020-02-11 23:21 ` + lib-ts_fsm-replace-zero-length-array-with-flexible-array-member.patch " Andrew Morton
2020-02-11 23:21 ` + lib-ts_kmp-replace-zero-length-array-with-flexible-array-member.patch " Andrew Morton
2020-02-11 23:23 ` + mm-rmap-annotate-a-data-race-at-tlb_flush_batched.patch " Andrew Morton
2020-02-11 23:26 ` + mm-mempool-fix-a-data-race-in-mempool_free.patch " Andrew Morton
2020-02-11 23:53 ` + mm-kmemleak-annotate-a-data-race-in-checksum.patch " Andrew Morton
2020-02-12 0:19 ` + mm-adjust-shuffle-code-to-allow-for-future-coalescing.patch " Andrew Morton
2020-02-12 0:19 ` + mm-use-zone-and-order-instead-of-free-area-in-free_list-manipulators.patch " Andrew Morton
2020-02-12 0:19 ` + mm-add-function-__putback_isolated_page.patch " Andrew Morton
2020-02-12 0:19 ` + mm-introduce-reported-pages.patch " Andrew Morton
2020-02-12 0:19 ` + virtio-balloon-pull-page-poisoning-config-out-of-free-page-hinting.patch " Andrew Morton
2020-02-12 0:19 ` + virtio-balloon-add-support-for-providing-free-page-reports-to-host.patch " Andrew Morton
2020-02-12 0:20 ` + mm-page_reporting-rotate-reported-pages-to-the-tail-of-the-list.patch " Andrew Morton
2020-02-12 0:20 ` + mm-page_reporting-add-budget-limit-on-how-many-pages-can-be-reported-per-pass.patch " Andrew Morton
2020-02-12 0:20 ` + mm-page_reporting-add-free-page-reporting-documentation.patch " Andrew Morton
2020-02-12 0:30 ` + mm-page_counter-fix-various-data-races.patch " Andrew Morton
2020-02-12 0:33 ` + memcg-lost-css_put-in-memcg_expand_shrinker_maps.patch " Andrew Morton
2020-02-12 21:16 ` + mm-page_counter-fix-various-data-races-at-memsw.patch " Andrew Morton
2020-02-12 21:16 ` [to-be-updated] mm-page_counter-fix-various-data-races.patch removed from " Andrew Morton
2020-02-12 21:18 ` + mm-swapfilec-fix-comments-for-swapcache_prepare.patch added to " Andrew Morton
2020-02-12 21:22 ` + mm-util-annotate-an-data-race-at-vm_committed_as.patch " Andrew Morton
2020-02-12 22:08 ` + asm-generic-fix-unistd_32h-generation-format.patch " Andrew Morton
2020-02-12 22:26 ` + mm-dont-bother-dropping-mmap_sem-for-zero-size-readahead.patch " Andrew Morton
2020-02-12 22:34 ` + lib-scatterlist-fix-sg_copy_buffer-kerneldoc.patch " Andrew Morton
2020-02-12 22:59 ` + mm-allocate-shrinker_map-on-appropriate-numa-node.patch " Andrew Morton
2020-02-12 23:05 ` + init-cleanup-anon_inodes-and-old-io-schedulers-options.patch " Andrew Morton
2020-02-12 23:10 ` + checkpatch-check-spdx-tags-in-yaml-files.patch " Andrew Morton
2020-02-13 2:16 ` + drivers-base-memoryc-indicate-all-memory-blocks-as-removable.patch " Andrew Morton
2020-02-13 2:56 ` + mm-refactor-insert_page-to-prepare-for-batched-lock-insert.patch " Andrew Morton
2020-02-13 2:56 ` + mm-add-vm_insert_pages.patch " Andrew Morton
2020-02-13 2:57 ` + mm-add-vm_insert_pages-fix.patch " Andrew Morton
2020-02-13 2:57 ` + net-zerocopy-use-vm_insert_pages-for-tcp-rcv-zerocopy.patch " Andrew Morton
2020-02-13 2:57 ` + net-zerocopy-use-vm_insert_pages-for-tcp-rcv-zerocopy-fix.patch " Andrew Morton
2020-02-14 2:50 ` + mm-add-vm_insert_pages-2.patch " Andrew Morton
2020-02-14 2:52 ` + mm-migratec-no-need-to-check-for-i-start-in-do_pages_move.patch " Andrew Morton
2020-02-14 2:52 ` + mm-migratec-wrap-do_move_pages_to_node-and-store_status.patch " Andrew Morton
2020-02-14 2:52 ` + mm-migratec-check-pagelist-in-move_pages_and_store_status.patch " Andrew Morton
2020-02-14 2:52 ` + mm-migratec-unify-not-queued-for-migration-handling-in-do_pages_move.patch " Andrew Morton
2020-02-14 2:57 ` + mm-migratec-migrate-pg_readahead-flag.patch " Andrew Morton
2020-02-14 2:57 ` + mm-migratec-migrate-pg_readahead-flag-fix.patch " Andrew Morton
2020-02-14 2:58 ` + include-remove-highmemh-from-pagemaph.patch " Andrew Morton
2020-02-14 3:06 ` + mm-kmemleak-annotate-various-data-races-obj-ptr.patch " Andrew Morton
2020-02-14 3:06 ` [to-be-updated] mm-kmemleak-annotate-a-data-race-in-checksum.patch removed from " Andrew Morton
2020-02-14 3:26 ` + mm-swapfile-fix-and-annotate-various-data-races-v2.patch added to " Andrew Morton
2020-02-14 3:27 ` + mm-page_io-mark-various-intentional-data-races-v2.patch " Andrew Morton
2020-02-14 5:10 ` + checkpatch-support-base-commit-format.patch " Andrew Morton
2020-02-14 5:11 ` + checkpatch-prefer-fallthrough-over-fallthrough-comments.patch " Andrew Morton
2020-02-14 5:12 ` + uapi-fix-userspace-breakage-use-__bits_per_long-for-swap.patch " Andrew Morton
2020-02-14 5:15 ` + lib-string-update-match_string-doc-strings-with-correct-behavior.patch " Andrew Morton
2020-02-14 5:16 ` + mm-vmscan-replace-open-codings-to-numa_no_node.patch " Andrew Morton
2020-02-14 5:19 ` + mm-mempolicy-support-mpol_mf_strict-for-huge-page-mapping.patch " Andrew Morton
2020-02-14 5:22 ` + mm-vmscan-dont-round-up-scan-size-for-online-memory-cgroup.patch " Andrew Morton
2020-02-14 5:26 ` + mm-mempolicy-use-vm_bug_on_vma-in-queue_pages_test_walk.patch " Andrew Morton
2020-02-14 5:30 ` + drivers-base-memoryc-drop-section_count.patch " Andrew Morton
2020-02-14 5:31 ` + drivers-base-memoryc-drop-pages_correctly_probed.patch " Andrew Morton
2020-02-14 5:31 ` + mm-page_extc-drop-pfn_present-check-when-onlining.patch " Andrew Morton
2020-02-14 5:41 ` [failures] include-remove-highmemh-from-pagemaph.patch removed from " Andrew Morton
2020-02-14 6:26 ` mmotm 2020-02-13-22-26 uploaded Andrew Morton
2020-02-24 2:45 ` + mm-debug-add-tests-validating-architecture-page-table-helpers.patch added to -mm tree Andrew Morton
2020-02-24 3:20 ` + proc-faster-open-read-close-with-permanent-files.patch " Andrew Morton
2020-02-24 3:24 ` + proc-faster-open-read-close-with-permanent-files-checkpatch-fixes.patch " Andrew Morton
2020-02-24 3:25 ` + psi-move-pf_memstall-into-psi-specific-psi_flags.patch " Andrew Morton
2020-02-24 3:29 ` + mm-hugetlb-fix-a-addressing-exception-caused-by-huge_pte_offset.patch " Andrew Morton
2020-02-24 3:31 ` + ocfs2-there-is-no-need-to-log-twice-in-several-functions.patch " Andrew Morton
2020-02-24 3:31 ` + ocfs2-correct-annotation-from-l_next_rec-to-l_next_free_rec.patch " Andrew Morton
2020-02-24 3:46 ` + hugetlb-support-file_region-coalescing-again-fix-2.patch " Andrew Morton
2020-02-24 3:53 ` + fat-fix-uninit-memory-access-for-partial-initialized-inode.patch " Andrew Morton
2020-02-24 4:08 ` + mm-add-mremap_dontunmap-to-mremap-v7.patch " Andrew Morton
2020-02-24 4:08 ` + selftest-add-mremap_dontunmap-selftest-v7.patch " Andrew Morton
2020-02-24 4:08 ` + selftest-add-mremap_dontunmap-selftest-v7-checkpatch-fixes.patch " Andrew Morton
2020-02-24 4:10 ` + percpu_counter-fix-a-data-race-at-vm_committed_as.patch " Andrew Morton
2020-02-24 4:10 ` + lib-test_lockup-fix-spelling-mistake-iteraions-iterations.patch " Andrew Morton
2020-02-24 21:40 ` + mm-swapfile-fix-data-races-in-try_to_unuse.patch " Andrew Morton
2020-02-24 21:45 ` [nacked] psi-move-pf_memstall-into-psi-specific-psi_flags.patch removed from " Andrew Morton
2020-02-24 21:57 ` + mm-z3fold-do-not-include-rwlockh-directly.patch added to " Andrew Morton
2020-02-24 22:04 ` + mm-hotplug-fix-page-online-with-debug_pagealloc-compiled-but-not-enabled.patch " Andrew Morton
2020-02-24 22:13 ` + mm-vma-add-missing-vma-flag-readable-name-for-vm_sync.patch " Andrew Morton
2020-02-24 22:13 ` + mm-vma-make-vma_is_accessible-available-for-general-use.patch " Andrew Morton
2020-02-24 22:13 ` + mm-vma-replace-all-remaining-open-encodings-with-is_vm_hugetlb_page.patch " Andrew Morton
2020-02-24 22:13 ` + mm-vma-replace-all-remaining-open-encodings-with-vma_is_anonymous.patch " Andrew Morton
2020-02-24 22:14 ` + mm-vma-append-unlikely-while-testing-vma-access-permissions.patch " Andrew Morton
2020-02-24 22:30 ` + samples-hw_breakpoint-drop-hw_breakpoint_r-when-reporting-writes.patch " Andrew Morton
2020-02-24 22:31 ` + samples-hw_breakpoint-drop-use-of-kallsyms_lookup_name.patch " Andrew Morton
2020-02-24 22:31 ` + kallsyms-unexport-kallsyms_lookup_name-and-kallsyms_on_each_symbol.patch " Andrew Morton
2020-02-24 22:55 ` + loop-use-worker-per-cgroup-instead-of-kworker.patch " Andrew Morton
2020-02-24 22:55 ` + mm-charge-active-memcg-when-no-mm-is-set.patch " Andrew Morton
2020-02-24 22:55 ` + loop-charge-i-o-to-mem-and-blk-cg.patch " Andrew Morton
2020-02-24 23:33 ` + mm-mempolicy-checking-hugepage-migration-is-supported-by-arch-in-vma_migratable.patch " Andrew Morton
2020-02-24 23:39 ` + checkpatch-fix-minor-typo-and-mixed-spacetab-in-indentation.patch " Andrew Morton
2020-02-24 23:40 ` + checkpatch-fix-multiple-const-types.patch " Andrew Morton
2020-02-24 23:40 ` + checkpatch-add-command-line-option-for-tab-size.patch " Andrew Morton
2020-02-24 23:43 ` + lib-test_bitmap-make-use-of-exp2_in_bits.patch " Andrew Morton
2020-02-24 23:44 ` + ocfs2-remove-useless-err.patch " Andrew Morton
2020-02-25 0:26 ` + arch-kconfig-update-have_reliable_stacktrace-description.patch " Andrew Morton
2020-02-25 0:32 ` + mm-memcg-slab-introduce-mem_cgroup_from_obj.patch " Andrew Morton
2020-02-25 0:47 ` + mm-kmem-cleanup-__memcg_kmem_charge_memcg-arguments.patch " Andrew Morton
2020-02-25 0:48 ` + mm-kmem-cleanup-memcg_kmem_uncharge_memcg-arguments.patch " Andrew Morton
2020-02-25 0:48 ` + mm-kmem-rename-memcg_kmem_uncharge-into-memcg_kmem_uncharge_page.patch " Andrew Morton
2020-02-25 0:48 ` + mm-kmem-switch-to-nr_pages-in-__memcg_kmem_charge_memcg.patch " Andrew Morton
2020-02-25 0:48 ` + mm-memcg-slab-cache-page-number-in-memcg_uncharge_slab.patch " Andrew Morton
2020-02-25 0:48 ` + mm-kmem-rename-__memcg_kmem_uncharge_memcg-to-__memcg_kmem_uncharge.patch " Andrew Morton
2020-02-25 2:29 ` + mm-memcg-slab-introduce-mem_cgroup_from_obj-v2.patch " Andrew Morton
2020-02-25 2:36 ` + ocfs2-add-missing-annotations-for-ocfs2_refcount_cache_lock-and-ocfs2_refcount_cache_unlock.patch " Andrew Morton
2020-02-25 3:53 ` mmotm 2020-02-24-19-53 uploaded Andrew Morton
2020-02-26 1:06 ` + checkpatch-improve-gerrit-change-id-test.patch added to -mm tree Andrew Morton
2020-02-26 1:55 ` + dma-buf-free-dmabuf-name-in-dma_buf_release.patch " Andrew Morton
[not found] ` <CAO_48GFr9-aY4=kRqWB=UkEzPj5fQDip+G1tNZMsT0XoQpBC7Q@mail.gmail.com>
[not found] ` <CAKMK7uGvixQ2xoQMt3pvt0OpNXDjDGTvSWsaAppsKrmO_EP3Kg@mail.gmail.com>
2020-02-27 4:20 ` Andrew Morton
2020-02-26 3:42 ` + lib-rbtree-fix-coding-style-of-assignments.patch " Andrew Morton
2020-02-26 3:56 ` + seq_read-info-message-about-buggy-next-functions.patch " Andrew Morton
[not found] ` <1583173259.7365.142.camel@lca.pw>
[not found] ` <1583177508.7365.144.camel@lca.pw>
2020-03-02 20:42 ` Andrew Morton
2020-02-26 3:56 ` + pstore_ftrace_seq_next-should-increase-position-index.patch " Andrew Morton
[not found] ` <07f968e6-02cd-de2a-e868-787e4bedd346@virtuozzo.com>
2020-02-27 4:26 ` Andrew Morton
2020-02-26 3:56 ` + gcov_seq_next-should-increase-position-index.patch " Andrew Morton
2020-02-26 3:56 ` + sysvipc_find_ipc-should-increase-position-index.patch " Andrew Morton
2020-02-27 1:19 ` + mm-bring-sparc-pte_index-semantics-inline-with-other-platforms.patch " Andrew Morton
2020-02-27 1:37 ` + mm-vmscan-fix-data-races-at-kswapd_classzone_idx.patch " Andrew Morton
2020-02-27 1:49 ` + fs-epoll-make-nesting-accounting-safe-for-rt-kernel.patch " Andrew Morton
2020-02-27 3:50 ` + lib-optimize-cpumask_local_spread.patch " Andrew Morton
2020-02-27 4:04 ` + mm-debug-add-tests-validating-architecture-page-table-helpers-fix.patch " Andrew Morton
2020-02-27 4:11 ` + gcov-gcc_4_7-replace-zero-length-array-with-flexible-array-member.patch " Andrew Morton
2020-02-27 4:42 ` + mm-debug-add-tests-validating-architecture-page-table-helpers-fix-2.patch " Andrew Morton
2020-02-27 4:42 ` [to-be-updated] mm-debug-add-tests-validating-architecture-page-table-helpers-fix.patch removed from " Andrew Morton
2020-02-27 4:44 ` + huge-tmpfs-try-to-split_huge_page-when-punching-hole.patch added to " Andrew Morton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200211055041.F8LyqvT8s%akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=david@fromorbit.com \
--cc=hch@infradead.org \
--cc=ira.weiny@intel.com \
--cc=jack@suse.cz \
--cc=jgg@ziepe.ca \
--cc=jglisse@redhat.com \
--cc=jhubbard@nvidia.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhocko@suse.com \
--cc=mike.kravetz@oracle.com \
--cc=mm-commits@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=vbabka@suse.cz \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).