linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* A mapcount riddle
@ 2023-01-24 20:56 Mike Kravetz
  2023-01-24 23:00 ` Peter Xu
                   ` (3 more replies)
  0 siblings, 4 replies; 22+ messages in thread
From: Mike Kravetz @ 2023-01-24 20:56 UTC (permalink / raw)
  To: linux-mm
  Cc: Naoya Horiguchi, David Rientjes, Michal Hocko, Matthew Wilcox,
	David Hildenbrand, Peter Xu, James Houghton, Muchun Song

Q How can a page be mapped into multiple processes and have a
  mapcount of 1?

A It is a hugetlb page referenced by a shared PMD.

I was looking to expose some basic information about PMD sharing via
/proc/smaps.  After adding the code, I started a couple processes
sharing a large hugetlb mapping that would result in the use of
shared PMDs.  When I looked at the output of /proc/smaps, I saw
my new metric counting the number of shared PMDs.  However, what
stood out was that the entire mapping was listed as Private_Hugetlb.
WTH???  It certainly was shared!  The routine smaps_hugetlb_range
decides between Private_Hugetlb and Shared_Hugetlb with this code:

	if (page) {
		int mapcount = page_mapcount(page);

		if (mapcount >= 2)
			mss->shared_hugetlb += huge_page_size(hstate_vma(vma));
		else
			mss->private_hugetlb += huge_page_size(hstate_vma(vma));
	}

After spending some time looking for issues in the page_mapcount code,
I came to the realization that the mapcount of hugetlb pages only
referenced by a shared PMD would be 1 no matter how many processes had
mapped the page.  When a page is first faulted, the mapcount is set to 1.
When faulted in other processes, the shared PMD is added to the page
table of the other processes.  No increase of mapcount will occur.

At first thought this seems bad.  However, I believe this has been the
behavior since hugetlb PMD sharing was introduced in 2006 and I am
unaware of any reported issues.  I did a audit of code looking at
mapcount.  In addition to the above issue with smaps, there appears
to be an issue with 'migrate_pages' where shared pages could be migrated
without appropriate privilege.

	/* With MPOL_MF_MOVE, we migrate only unshared hugepage. */
	if (flags & (MPOL_MF_MOVE_ALL) ||
	    (flags & MPOL_MF_MOVE && page_mapcount(page) == 1)) {
		if (isolate_hugetlb(page, qp->pagelist) &&
			(flags & MPOL_MF_STRICT))
			/*
			 * Failed to isolate page but allow migrating pages
			 * which have been queued.
			 */
			ret = 1;
	}

I will prepare fixes for both of these.  However, I wanted to ask if
anyone has ideas about other potential issues with this?

Since COW is mostly relevant to private mappings, shared PMDs generally
do not apply.  Nothing stood out in a quick audit of code.
-- 
Mike Kravetz


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

end of thread, other threads:[~2023-01-27  9:56 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-24 20:56 A mapcount riddle Mike Kravetz
2023-01-24 23:00 ` Peter Xu
2023-01-24 23:29   ` Yang Shi
2023-01-25 16:02     ` Peter Xu
2023-01-25 18:26       ` Yang Shi
2023-01-24 23:35   ` Mike Kravetz
2023-01-25 16:46     ` Peter Xu
2023-01-25 18:16       ` Mike Kravetz
2023-01-25 20:13         ` Peter Xu
2023-01-25  8:24 ` Michal Hocko
2023-01-25 17:59   ` Mike Kravetz
2023-01-26  9:16     ` Michal Hocko
2023-01-26 17:51       ` Mike Kravetz
2023-01-27  9:56         ` Michal Hocko
2023-01-25  9:09 ` David Hildenbrand
2023-01-25 15:26 ` James Houghton
2023-01-25 15:54   ` Peter Xu
2023-01-25 16:22     ` James Houghton
2023-01-25 19:26       ` Vishal Moola
2023-01-26  9:15       ` David Hildenbrand
2023-01-26 18:22         ` Yang Shi
2023-01-26  9:10   ` David Hildenbrand

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