linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mm: __delete_from_page_cache WARN_ON(page_mapped)
@ 2016-02-29  4:49 Hugh Dickins
  2016-02-29  7:44 ` Joonsoo Kim
  2016-02-29  9:52 ` Kirill A. Shutemov
  0 siblings, 2 replies; 7+ messages in thread
From: Hugh Dickins @ 2016-02-29  4:49 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Kirill A. Shutemov, Joonsoo Kim, Sasha Levin, linux-mm,
	linux-kernel

Commit e1534ae95004 ("mm: differentiate page_mapped() from page_mapcount()
for compound pages") changed the famous BUG_ON(page_mapped(page)) in
__delete_from_page_cache() to VM_BUG_ON_PAGE(page_mapped(page)): which
gives us more info when CONFIG_DEBUG_VM=y, but nothing at all when not.

Although it has not usually been very helpul, being hit long after the
error in question, we do need to know if it actually happens on users'
systems; but reinstating a crash there is likely to be opposed :)

In the non-debug case, use WARN_ON() plus dump_page() and add_taint() -
I don't really believe LOCKDEP_NOW_UNRELIABLE, but that seems to be the
standard procedure now.  Move that, or the VM_BUG_ON_PAGE(), up before
the deletion from tree: so that the unNULLified page->mapping gives a
little more information.

If the inode is being evicted (rather than truncated), it won't have
any vmas left, so it's safe(ish) to assume that the raised mapcount is
erroneous, and we can discount it from page_count to avoid leaking the
page (I'm less worried by leaking the occasional 4kB, than losing a
potential 2MB page with each 4kB page leaked).

Signed-off-by: Hugh Dickins <hughd@google.com>
---
I think this should go into v4.5, so I've written it with an atomic_sub
on page->_count; but Joonsoo will probably want some page_ref thingy.

 mm/filemap.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

--- 4.5-rc6/mm/filemap.c	2016-02-28 09:04:38.816707844 -0800
+++ linux/mm/filemap.c	2016-02-28 19:45:23.406263928 -0800
@@ -195,6 +195,27 @@ void __delete_from_page_cache(struct pag
 	else
 		cleancache_invalidate_page(mapping, page);
 
+	VM_BUG_ON_PAGE(page_mapped(page), page);
+	if (!IS_ENABLED(CONFIG_DEBUG_VM) && WARN_ON(page_mapped(page))) {
+		int mapcount;
+
+		dump_page(page, "still mapped when deleted");
+		add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
+
+		mapcount = page_mapcount(page);
+		if (mapping_exiting(mapping) &&
+		    page_count(page) >= mapcount + 2) {
+			/*
+			 * All vmas have already been torn down, so it's
+			 * a good bet that actually the page is unmapped,
+			 * and we'd prefer not to leak it: if we're wrong,
+			 * some other bad page check should catch it later.
+			 */
+			page_mapcount_reset(page);
+			atomic_sub(mapcount, &page->_count);
+		}
+	}
+
 	page_cache_tree_delete(mapping, page, shadow);
 
 	page->mapping = NULL;
@@ -205,7 +226,6 @@ void __delete_from_page_cache(struct pag
 		__dec_zone_page_state(page, NR_FILE_PAGES);
 	if (PageSwapBacked(page))
 		__dec_zone_page_state(page, NR_SHMEM);
-	VM_BUG_ON_PAGE(page_mapped(page), page);
 
 	/*
 	 * At this point page must be either written or cleaned by truncate.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-04-18 15:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-29  4:49 [PATCH] mm: __delete_from_page_cache WARN_ON(page_mapped) Hugh Dickins
2016-02-29  7:44 ` Joonsoo Kim
2016-02-29  9:52 ` Kirill A. Shutemov
2016-03-01  6:43   ` Hugh Dickins
2016-03-01  6:45     ` [PATCH] mm: __delete_from_page_cache show Bad page if mapped Hugh Dickins
2016-03-01 11:16       ` Kirill A. Shutemov
2016-04-18 15:06       ` Sasha Levin

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).