Skip to contentSkip to conversation

hugetlb pages not accounted for in rss

PATCH Superseded Mike Kravetz 8 participants 71 messages Jul 27, 2015 – Sep 17, 2015

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

I started looking at the hugetlb self tests. The test hugetlbfstest expects hugetlb pages to be accounted for in rss. However, there is no code in the kernel to do this accounting.

It looks like there was an effort to add the accounting back in 2013. The test program made it into tree, but the accounting code did not.

The easiest way to resolve this issue would be to remove the test and perhaps document that hugetlb pages are not accounted for in rss. However, it does seem like a big oversight that hugetlb pages are not accounted for in rss. From a quick scan of the code it appears THP pages are properly accounted for.

Thoughts?

Signature · 7 lines
Mike Kravetz

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#1 lore raw
Quoted 6 lines · Mike Kravetz

I started looking at the hugetlb self tests. The test hugetlbfstest expects hugetlb pages to be accounted for in rss. However, there is no code in the kernel to do this accounting.

It looks like there was an effort to add the accounting back in 2013. The test program made it into tree, but the accounting code did not.

My apologies. Upstream work always gets axed first when I run out of time - which happens more often than not.

Quoted 7 lines

The easiest way to resolve this issue would be to remove the test and perhaps document that hugetlb pages are not accounted for in rss. However, it does seem like a big oversight that hugetlb pages are not accounted for in rss. From a quick scan of the code it appears THP pages are properly accounted for.

Thoughts?

Unsurprisingly I agree that hugepages should count towards rss. Keeping the test in keeps us honest. Actually fixing the issue would make us honest and correct.

Increasingly we have tiny processes (by rss) that actually consume large fractions of total memory. Makes rss somewhat useless as a measure of anything.

Jorn

--
Consensus is no proof!
-- John Naisbitt

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

#2 lore raw
Quoted 10 lines · Jorn Engel
Quoted 6 lines · Mike Kravetz

I started looking at the hugetlb self tests. The test hugetlbfstest expects hugetlb pages to be accounted for in rss. However, there is no code in the kernel to do this accounting.

It looks like there was an effort to add the accounting back in 2013. The test program made it into tree, but the accounting code did not.

My apologies. Upstream work always gets axed first when I run out of time - which happens more often than not.

No worries, I just noticed the inconsistency of the test program and no supporting code in the kernel.

Quoted 8 lines
Quoted 7 lines

The easiest way to resolve this issue would be to remove the test and perhaps document that hugetlb pages are not accounted for in rss. However, it does seem like a big oversight that hugetlb pages are not accounted for in rss. From a quick scan of the code it appears THP pages are properly accounted for.

Thoughts?

Quoted 7 lines

Unsurprisingly I agree that hugepages should count towards rss. Keeping the test in keeps us honest. Actually fixing the issue would make us honest and correct.

Increasingly we have tiny processes (by rss) that actually consume large fractions of total memory. Makes rss somewhat useless as a measure of anything.

I'll take a look at what it would take to get the accounting in place.

Signature · 1 line
Mike Kravetz
Quoted 7 lines

Jorn

--
Consensus is no proof!
-- John Naisbitt

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

#3 lore raw
Quoted 12 lines · Mike Kravetz
Quoted 12 lines
Quoted 7 lines

The easiest way to resolve this issue would be to remove the test and perhaps document that hugetlb pages are not accounted for in rss. However, it does seem like a big oversight that hugetlb pages are not accounted for in rss. From a quick scan of the code it appears THP pages are properly accounted for.

Thoughts?

Unsurprisingly I agree that hugepages should count towards rss. Keeping the test in keeps us honest. Actually fixing the issue would make us honest and correct.

Quoted 5 lines
Quoted 3 lines

Increasingly we have tiny processes (by rss) that actually consume large fractions of total memory. Makes rss somewhat useless as a measure of anything.

I'll take a look at what it would take to get the accounting in place.

I'm not sure that I would agree that accounting hugetlb pages in rss would always be appropriate.

For reserved hugetlb pages, not surplus, the hugetlb pages are always resident even when unmapped. Unmapping the memory is not going to cause them to be freed. That's different from thp where the hugepages are actually freed when you do munmap().

The oom killer looks at rss as the metric to determine which process to kill that will result in a large amount of memory freeing. If hugetlb pages are accounted in rss, this may lead to unnecessary killing since little memory may be freed as a result.

For that reason, we've added hugetlb statistics to the oom killer output since we've been left wondering in the past where all the memory on the system went :)

We also have a separate hugetlb cgroup that tracks hugetlb memory usage rather than memcg.

Starting to account hugetlb pages in rss may lead to breakage in userspace and I would agree with your earlier suggestion that just removing any test for rss would be appropriate.

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

#4 lore raw
Quoted 4 lines · David Rientjes

Starting to account hugetlb pages in rss may lead to breakage in userspace and I would agree with your earlier suggestion that just removing any test for rss would be appropriate.

What would you propose for me then? I have 80% RAM or more in reserved hugepages. OOM-killer is not a concern, as it panics the system - the alternatives were almost universally silly and we didn't want to deal with system in unpredictable states. But knowing how much memory is used by which process is a concern. And if you only tell me about the small (and continuously shrinking) portion, I essentially fly blind.

That is not a case of "may lead to breakage", it _is_ broken.

Ideally we would have fixed this in 2002 when hugetlbfs was introduced. By now we might have to introduce a new field, rss_including_hugepages or whatever. Then we have to update tools like top etc. to use the new field when appropriate. No fun, but might be necessary.

If we can get away with including hugepages in rss and fixing the OOM killer to be less silly, I would strongly prefer that. But I don't know how much of a mess we are already in.

Jorn

--
Time? What's that? Time is only worth what you do with it. -- Theo de Raadt

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

#5 lore raw
Quoted 9 lines · Jorn Engel

What would you propose for me then? I have 80% RAM or more in reserved hugepages. OOM-killer is not a concern, as it panics the system - the alternatives were almost universally silly and we didn't want to deal with system in unpredictable states. But knowing how much memory is used by which process is a concern. And if you only tell me about the small (and continuously shrinking) portion, I essentially fly blind.

That is not a case of "may lead to breakage", it _is_ broken.

Quoted 9 lines

Ideally we would have fixed this in 2002 when hugetlbfs was introduced. By now we might have to introduce a new field, rss_including_hugepages or whatever. Then we have to update tools like top etc. to use the new field when appropriate. No fun, but might be necessary.

If we can get away with including hugepages in rss and fixing the OOM killer to be less silly, I would strongly prefer that. But I don't know how much of a mess we are already in.

It's not only the oom killer, I don't believe hugeltb pages are accounted to the "rss" in memcg. They use the hugetlb_cgroup for that. Starting to account for them in existing memcg deployments would cause them to hit their memory limits much earlier. The "rss_huge" field in memcg only represents transparent hugepages.

I agree with your comment that having done this when hugetlbfs was introduced would have been optimal.

It's always difficult to add a new class of memory to an existing metric ("new" here because it's currently unaccounted).

If we can add yet another process metric to track hugetlbfs memory mapped, then the test could be converted to use that. I'm not sure if the jusitifcation would be strong enough, but you could try.

#6 lore raw
Quoted 10 lines · David Rientjes

It's not only the oom killer, I don't believe hugeltb pages are accounted to the "rss" in memcg. They use the hugetlb_cgroup for that. Starting to account for them in existing memcg deployments would cause them to hit their memory limits much earlier. The "rss_huge" field in memcg only represents transparent hugepages.

I agree with your comment that having done this when hugetlbfs was introduced would have been optimal.

Quoted 6 lines

It's always difficult to add a new class of memory to an existing metric ("new" here because it's currently unaccounted).

If we can add yet another process metric to track hugetlbfs memory mapped, then the test could be converted to use that. I'm not sure if the jusitifcation would be strong enough, but you could try.

Well, we definitely need something. Having a 100GB process show 3GB of rss is not very useful. How would we notice a memory leak if it only affects hugepages, for example?

Jorn

--
The object-oriented version of 'Spaghetti code' is, of course, 'Lasagna code'. (Too many layers).
-- Roberto Waltman.

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

#7 lore raw
Quoted 4 lines · Jorn Engel

Well, we definitely need something. Having a 100GB process show 3GB of rss is not very useful. How would we notice a memory leak if it only affects hugepages, for example?

Since the hugetlb pool is a global resource, it would also be helpful to determine if a process is mapping more than expected. You can't do that just by adding a huge rss metric, however: if you have 2MB and 1GB hugepages configured you wouldn't know if a process was mapping 512 2MB hugepages or 1 1GB hugepage.

That's the purpose of hugetlb_cgroup, after all, and it supports usage counters for all hstates. The test could be converted to use that to measure usage if configured in the kernel.

Beyond that, I'm not sure how a per-hstate rss metric would be exported to userspace in a clean way and other ways of obtaining the same data are possible with hugetlb_cgroup. I'm not sure how successful you'd be in arguing that we need separate rss counters for it.

#8 lore raw
Quoted 13 lines · David Rientjes
Quoted 4 lines · Jörn Engel

Well, we definitely need something. Having a 100GB process show 3GB of rss is not very useful. How would we notice a memory leak if it only affects hugepages, for example?

Since the hugetlb pool is a global resource, it would also be helpful to determine if a process is mapping more than expected. You can't do that just by adding a huge rss metric, however: if you have 2MB and 1GB hugepages configured you wouldn't know if a process was mapping 512 2MB hugepages or 1 1GB hugepage.

Quoted 8 lines

That's the purpose of hugetlb_cgroup, after all, and it supports usage counters for all hstates. The test could be converted to use that to measure usage if configured in the kernel.

Beyond that, I'm not sure how a per-hstate rss metric would be exported to userspace in a clean way and other ways of obtaining the same data are possible with hugetlb_cgroup. I'm not sure how successful you'd be in arguing that we need separate rss counters for it.

If I want to track hugetlb usage on a per-task basis, do I then need to create one cgroup per task?

For example, suppose I have many tasks using hugetlb and the global pool is getting low on free pages. It might be useful to know which tasks are using hugetlb pages, and how many they are using.

I don't actually have this need (I think), but it appears to be what Jörn is asking for.

Signature · 1 line
Mike Kravetz
#9 lore raw
Quoted 6 lines · Mike Kravetz
Quoted 6 lines

Since the hugetlb pool is a global resource, it would also be helpful to determine if a process is mapping more than expected. You can't do that just by adding a huge rss metric, however: if you have 2MB and 1GB hugepages configured you wouldn't know if a process was mapping 512 2MB hugepages or 1 1GB hugepage.

Fair, although I believe 1GB hugepages are overrated. If you assume that per-page overhead is independent of page size (not quite true, but close enough), going from 1% small pages to 0.8% small pages will improve performance as much as going from 99% 2MB pages to 99% 1GB pages.

Quoted 12 lines
Quoted 8 lines

That's the purpose of hugetlb_cgroup, after all, and it supports usage counters for all hstates. The test could be converted to use that to measure usage if configured in the kernel.

Beyond that, I'm not sure how a per-hstate rss metric would be exported to userspace in a clean way and other ways of obtaining the same data are possible with hugetlb_cgroup. I'm not sure how successful you'd be in arguing that we need separate rss counters for it.

If I want to track hugetlb usage on a per-task basis, do I then need to create one cgroup per task?

Quoted 6 lines

For example, suppose I have many tasks using hugetlb and the global pool is getting low on free pages. It might be useful to know which tasks are using hugetlb pages, and how many they are using.

I don't actually have this need (I think), but it appears to be what Jorn is asking for.

Maybe some background is useful. I would absolutely love to use transparent hugepages. They are absolutely perfect in every respect, except for performance. With transparent hugepages we get higher latencies. Small pages are unacceptable, so we are forced to use non-transparent hugepages.

The part of our system that uses small pages is pretty much constant, while total system memory follows Moore's law. When possible we even try to shrink that part. Hugepages already dominate today and things will get worse.

But otherwise we have all the problems that others also have. There are memory leaks and we would like to know how much memory each process actually uses. Most people use rss, while we have nothing good. And I am not sure if cgroup is the correct answer for essentially fixing a regression introduced in 2002.

Jorn

--
You cannot suppose that Moliere ever troubled himself to be original in the matter of ideas. You cannot suppose that the stories he tells in his plays have never been told before. They were culled, as you very well know. -- Andre-Louis Moreau in Scarabouche

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

#10 lore raw
Quoted 3 lines · Jorn Engel
Quoted 3 lines

If I want to track hugetlb usage on a per-task basis, do I then need to create one cgroup per task?

I think this would only be used for debugging or testing, but if you have root and are trying to organize processes into a hugetlb_cgroup hierarchy, presumably you would just look at smaps and find each thread's hugetlb memory usage and not bother.

Quoted 6 lines

Maybe some background is useful. I would absolutely love to use transparent hugepages. They are absolutely perfect in every respect, except for performance. With transparent hugepages we get higher latencies. Small pages are unacceptable, so we are forced to use non-transparent hugepages.

Believe me, we are on the same page that way :) We still deploy configurations with hugetlb memory because we need to meet certain allocation requirements and it is only possible to do at boot.

With regard to the performance of thp, I can think of two things that are affecting you:

- allocation cost

Async memory compaction in the page fault path for thp memory is very lightweight and it happily falls back to using small pages instead. Memory compaction is always being improved upon and there is on-going work to do memory compaction both periodically and in the background to keep fragmentation low. The ultimate goal would be to remove async compaction entirely from the thp page fault path and rely on improvements to memory compaction such that we have a great allocation success rate and less cost when we fail.

- NUMA cost

Until very recently, thp pages could easily be allocated remotely instead of small pages locally. That has since been improved and we only allocate thp locally and then fallback to small pages locally first. Khugepaged can still migrate memory remotely, but it will allocate the hugepage on the node where the majority of smallpages are from.

Quoted 5 lines

The part of our system that uses small pages is pretty much constant, while total system memory follows Moore's law. When possible we even try to shrink that part. Hugepages already dominate today and things will get worse.

I wrote a patchset, hugepages overcommit, that allows unmapped hugetlb pages to be freed in oom conditions before calling the oom killer up to a certain threshold and then kickoff a background thread to try to reallocate them. The idea is to keep the hugetlb pool as large as possible up to oom and then only reclaim what is needed and then try to reallocate them. Not sure if it would help your particular usecase or not.

#11 lore raw
In reply to Mike Kravetz

T24gV2VkLCBKdWwgMjksIDIwMTUgYXQgMDQ6MjA6NTlQTSAtMDcwMCwgTWlrZSBLcmF2ZXR6IHdy b3RlOg0KPiBPbiAwNy8yOS8yMDE1IDEyOjA4IFBNLCBEYXZpZCBSaWVudGplcyB3cm90ZToNCj4g Pk9uIFR1ZSwgMjggSnVsIDIwMTUsIErDtnJuIEVuZ2VsIHdyb3RlOg0KPiA+DQo+ID4+V2VsbCwg d2UgZGVmaW5pdGVseSBuZWVkIHNvbWV0aGluZy4gIEhhdmluZyBhIDEwMEdCIHByb2Nlc3Mgc2hv dyAzR0Igb2YNCj4gPj5yc3MgaXMgbm90IHZlcnkgdXNlZnVsLiAgSG93IHdvdWxkIHdlIG5vdGlj ZSBhIG1lbW9yeSBsZWFrIGlmIGl0IG9ubHkNCj4gPj5hZmZlY3RzIGh1Z2VwYWdlcywgZm9yIGV4 YW1wbGU/DQo+ID4+DQo+ID4NCj4gPlNpbmNlIHRoZSBodWdldGxiIHBvb2wgaXMgYSBnbG9iYWwg cmVzb3VyY2UsIGl0IHdvdWxkIGFsc28gYmUgaGVscGZ1bCB0bw0KPiA+ZGV0ZXJtaW5lIGlmIGEg cHJvY2VzcyBpcyBtYXBwaW5nIG1vcmUgdGhhbiBleHBlY3RlZC4gIFlvdSBjYW4ndCBkbyB0aGF0 DQo+ID5qdXN0IGJ5IGFkZGluZyBhIGh1Z2UgcnNzIG1ldHJpYywgaG93ZXZlcjogaWYgeW91IGhh dmUgMk1CIGFuZCAxR0INCj4gPmh1Z2VwYWdlcyBjb25maWd1cmVkIHlvdSB3b3VsZG4ndCBrbm93 IGlmIGEgcHJvY2VzcyB3YXMgbWFwcGluZyA1MTIgMk1CDQo+ID5odWdlcGFnZXMgb3IgMSAxR0Ig aHVnZXBhZ2UuDQo+ID4NCj4gPlRoYXQncyB0aGUgcHVycG9zZSBvZiBodWdldGxiX2Nncm91cCwg YWZ0ZXIgYWxsLCBhbmQgaXQgc3VwcG9ydHMgdXNhZ2UNCj4gPmNvdW50ZXJzIGZvciBhbGwgaHN0 YXRlcy4gIFRoZSB0ZXN0IGNvdWxkIGJlIGNvbnZlcnRlZCB0byB1c2UgdGhhdCB0bw0KPiA+bWVh c3VyZSB1c2FnZSBpZiBjb25maWd1cmVkIGluIHRoZSBrZXJuZWwuDQo+ID4NCj4gPkJleW9uZCB0 aGF0LCBJJ20gbm90IHN1cmUgaG93IGEgcGVyLWhzdGF0ZSByc3MgbWV0cmljIHdvdWxkIGJlIGV4 cG9ydGVkIHRvDQo+ID51c2Vyc3BhY2UgaW4gYSBjbGVhbiB3YXkgYW5kIG90aGVyIHdheXMgb2Yg b2J0YWluaW5nIHRoZSBzYW1lIGRhdGEgYXJlDQo+ID5wb3NzaWJsZSB3aXRoIGh1Z2V0bGJfY2dy b3VwLiAgSSdtIG5vdCBzdXJlIGhvdyBzdWNjZXNzZnVsIHlvdSdkIGJlIGluDQo+ID5hcmd1aW5n IHRoYXQgd2UgbmVlZCBzZXBhcmF0ZSByc3MgY291bnRlcnMgZm9yIGl0Lg0KPg0KPiBJZiBJIHdh bnQgdG8gdHJhY2sgaHVnZXRsYiB1c2FnZSBvbiBhIHBlci10YXNrIGJhc2lzLCBkbyBJIHRoZW4g bmVlZCB0bw0KPiBjcmVhdGUgb25lIGNncm91cCBwZXIgdGFzaz8NCj4NCj4gRm9yIGV4YW1wbGUs IHN1cHBvc2UgSSBoYXZlIG1hbnkgdGFza3MgdXNpbmcgaHVnZXRsYiBhbmQgdGhlIGdsb2JhbCBw b29sDQo+IGlzIGdldHRpbmcgbG93IG9uIGZyZWUgcGFnZXMuICBJdCBtaWdodCBiZSB1c2VmdWwg dG8ga25vdyB3aGljaCB0YXNrcyBhcmUNCj4gdXNpbmcgaHVnZXRsYiBwYWdlcywgYW5kIGhvdyBt YW55IHRoZXkgYXJlIHVzaW5nLg0KPg0KPiBJIGRvbid0IGFjdHVhbGx5IGhhdmUgdGhpcyBuZWVk IChJIHRoaW5rKSwgYnV0IGl0IGFwcGVhcnMgdG8gYmUgd2hhdA0KPiBKw7ZybiBpcyBhc2tpbmcg Zm9yLg0KDQpPbmUgcG9zc2libGUgd2F5IHRvIGdldCBodWdldGxiIG1ldHJpYyBpbiBwZXItdGFz ayBiYXNpcyBpcyB0byB3YWxrIHBhZ2UNCnRhYmxlIHZpYSAvcHJvYy9waWQvcGFnZW1hcCwgYW5k IGNvdW50aW5nIHBhZ2UgZmxhZ3MgZm9yIGVhY2ggbWFwcGVkIHBhZ2UNCih3ZSBjYW4gZWFzaWx5 IGRvIHRoaXMgd2l0aCB0b29scy92bS9wYWdlLXR5cGVzLmMgbGlrZSAicGFnZS10eXBlcyAtcCA8 UElEPg0KLWIgaHVnZSIpLiBUaGlzIGlzIG9idmlvdXNseSBzbG93ZXIgdGhhbiBqdXN0IHN0b3Jp bmcgdGhlIGNvdW50ZXIgYXMNCmluLWtlcm5lbCBkYXRhIGFuZCBqdXN0IGV4cG9ydGluZyBpdCwg YnV0IG1pZ2h0IGJlIHVzZWZ1bCBpbiBzb21lIHNpdHVhdGlvbi4NCg0KVGhhbmtzLA0KTmFveWEg SG9yaWd1Y2hp

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

#12 lore raw

PATCH 1/1 smaps: fill missing fields for vma(VM_HUGETLB)

Quoted 31 lines · Naoya Horiguchi
Quoted 30 lines · Mike Kravetz
Quoted 13 lines · David Rientjes
Quoted 4 lines · Jörn Engel

Well, we definitely need something. Having a 100GB process show 3GB of rss is not very useful. How would we notice a memory leak if it only affects hugepages, for example?

Since the hugetlb pool is a global resource, it would also be helpful to determine if a process is mapping more than expected. You can't do that just by adding a huge rss metric, however: if you have 2MB and 1GB hugepages configured you wouldn't know if a process was mapping 512 2MB hugepages or 1 1GB hugepage.

Quoted 8 lines

That's the purpose of hugetlb_cgroup, after all, and it supports usage counters for all hstates. The test could be converted to use that to measure usage if configured in the kernel.

Beyond that, I'm not sure how a per-hstate rss metric would be exported to userspace in a clean way and other ways of obtaining the same data are possible with hugetlb_cgroup. I'm not sure how successful you'd be in arguing that we need separate rss counters for it.

If I want to track hugetlb usage on a per-task basis, do I then need to create one cgroup per task?

For example, suppose I have many tasks using hugetlb and the global pool is getting low on free pages. It might be useful to know which tasks are using hugetlb pages, and how many they are using.

Quoted 8 lines
Quoted 2 lines

I don't actually have this need (I think), but it appears to be what Jörn is asking for.

One possible way to get hugetlb metric in per-task basis is to walk page table via /proc/pid/pagemap, and counting page flags for each mapped page (we can easily do this with tools/vm/page-types.c like "page-types -p <PID> -b huge"). This is obviously slower than just storing the counter as in-kernel data and just exporting it, but might be useful in some situation.

BTW, currently smaps doesn't report any meaningful info for vma(VM_HUGETLB). I wrote the following patch, which hopefully is helpful for your purpose.

Thanks,
Naoya Horiguchi

---
From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
 fs/proc/task_mmu.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
fs/proc/task_mmu.c +27 -0
index ca1e091881d4..c7218603306d 100644
@@ -610,12 +610,39 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		smaps_account(mss, page, huge_page_size(hstate_vma(vma)),
+			      pte_young(*pte), pte_dirty(*pte));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Acked-by on v1 1/1
#13 lore raw

Re: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

Quoted 7 lines · Naoya Horiguchi
Quoted 6 lines · Naoya Horiguchi

One possible way to get hugetlb metric in per-task basis is to walk page table via /proc/pid/pagemap, and counting page flags for each mapped page (we can easily do this with tools/vm/page-types.c like "page-types -p <PID> -b huge"). This is obviously slower than just storing the counter as in-kernel data and just exporting it, but might be useful in some situation.

Maybe. The current situation is a mess and I don't know the best way out of it yet.

Quoted 43 lines

BTW, currently smaps doesn't report any meaningful info for vma(VM_HUGETLB). I wrote the following patch, which hopefully is helpful for your purpose.

Thanks,
Naoya Horiguchi

---
From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB
Quoted 6 lines

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Nice!

Quoted 36 lines
---
 fs/proc/task_mmu.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
fs/proc/task_mmu.c +23 -0
index ca1e091881d4..c7218603306d 100644
@@ -610,12 +610,39 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		smaps_account(mss, page, huge_page_size(hstate_vma(vma)),
+			      pte_young(*pte), pte_dirty(*pte));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */

fs/proc/task_mmu.c static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) · line 645

Quoted 10 lines
fs/proc/task_mmu.c +4 -0
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif

Not too fond of the #ifdef. But I won't blame you, as there already is an example of the same and - worse - a contradicting example that unconditionally assigns and moved the #ifdef elsewhere.

Hugetlb is the unloved stepchild with 13 years of neglect and half-measures. It shows.

Patch looks good to me.

Jorn

--
Functionality is an asset, but code is a liability. --Ted Dziuba

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

#14 lore raw

Re: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

Quoted 43 lines · Jorn Engel
Quoted 36 lines

From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB
Quoted 6 lines

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Quoted 2 lines

Nice!

Hmm, wouldn't this be confusing since VmRSS in /proc/pid/status doesn't match the rss shown in smaps, since hugetlb mappings aren't accounted in get_mm_rss()?

Not sure this is a good idea, I think consistency amongst rss values would be more important.

#15 lore raw

Re: [PATCH] smaps: fill missing fields for vma(VM_HUGETLB)

On Wed, Aug 05, 2015 at 07:18:44PM -0700, David Rientjes wrote:
...

Quoted 6 lines

Hmm, wouldn't this be confusing since VmRSS in /proc/pid/status doesn't match the rss shown in smaps, since hugetlb mappings aren't accounted in get_mm_rss()?

Not sure this is a good idea, I think consistency amongst rss values would be more important.

Right, so one option is making get_mm_rss() count hugetlb, but that could make oom/memcg less efficient or broken as you stated in a previous email. So another one is to add "VmHugetlbRSS:" field in /proc/pid/status?

Thanks,
Naoya Horiguchi���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#22 lore raw

PATCH v2 2/2 mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

In reply to Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/pid/status.

This patch shouldn't change the OOM behavior (so hugetlb usage is ignored as is now,) which I guess is fine until we have some strong reason to do it.

---
 fs/proc/task_mmu.c       |  5 ++++-
 include/linux/hugetlb.h  | 18 ++++++++++++++++++
 include/linux/mm.h       |  3 +++
 include/linux/mm_types.h |  3 +++
 mm/hugetlb.c             |  9 +++++++++
 mm/memory.c              |  4 ++--
 mm/rmap.c                |  4 +++-
 7 files changed, 42 insertions(+), 4 deletions(-)
fs/proc/task_mmu.c +4 -1
index c7218603306d..f181f56fcce2 100644
@@ -22,7 +22,7 @@
 void task_mem(struct seq_file *m, struct mm_struct *mm)
 {
 	unsigned long data, text, lib, swap, ptes, pmds;
-	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss, hugetlb_rss;
 
 	/*
 	 * Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -37,6 +37,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 	hiwater_rss = total_rss = get_mm_rss(mm);
 	if (hiwater_rss < mm->hiwater_rss)
 		hiwater_rss = mm->hiwater_rss;
+	hugetlb_rss = get_hugetlb_rss(mm);
 
 	data = mm->total_vm - mm->shared_vm - mm->stack_vm;
 	text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
@@ -51,6 +52,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		"VmPin:\t%8lu kB\n"
 		"VmHWM:\t%8lu kB\n"
 		"VmRSS:\t%8lu kB\n"
+		"VmHugetlbRSS:\t%8lu kB\n"
 		"VmData:\t%8lu kB\n"
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
@@ -64,6 +66,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		mm->pinned_vm << (PAGE_SHIFT-10),
 		hiwater_rss << (PAGE_SHIFT-10),
 		total_rss << (PAGE_SHIFT-10),
+		hugetlb_rss << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
 		ptes >> 10,
include/linux/hugetlb.h +18 -0
index d891f949466a..6319df124e68 100644
@@ -469,6 +469,21 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+/*
+ * This simple wrappers are to hide MM_HUGETLBPAGES from outside hugetlbfs
+ * subsystem. The counter MM_HUGETLBPAGES is maintained in page unit basis,
+ * so it changes by 512 for example if a 2MB hugepage is mapped or unmapped.
+ */
+static inline int get_hugetlb_rss(struct mm_struct *mm)
+{
+	return get_mm_counter(mm, MM_HUGETLBPAGES);
+}
+
+static inline void mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+	add_mm_counter(mm, MM_HUGETLBPAGES, value);
+}
+
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +519,9 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+#define get_hugetlb_rss(mm)	0
+#define mod_hugetlb_rss(mm, value)	do {} while (0)
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm.h +3 -0
index 2e872f92dbac..9218a8856483 100644
@@ -1355,6 +1355,9 @@ static inline void sync_mm_rss(struct mm_struct *mm)
 }
 #endif
 
+extern inline void init_rss_vec(int *rss);
+extern inline void add_mm_rss_vec(struct mm_struct *mm, int *rss);
+
 int vma_wants_writenotify(struct vm_area_struct *vma);
 
 extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
include/linux/mm_types.h +3 -0
index 0038ac7466fd..887b43ba5a18 100644
@@ -348,6 +348,9 @@ enum {
 	MM_FILEPAGES,
 	MM_ANONPAGES,
 	MM_SWAPENTS,
+#ifdef CONFIG_HUGETLB_PAGE
+	MM_HUGETLBPAGES,
+#endif
 	NR_MM_COUNTERS
 };
 
mm/hugetlb.c +9 -0
index a8c3087089d8..12e5e7d3b60f 100644
@@ -2743,9 +2743,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	unsigned long mmun_start;	/* For mmu_notifiers */
 	unsigned long mmun_end;		/* For mmu_notifiers */
 	int ret = 0;
+	int rss[NR_MM_COUNTERS];
 
 	cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 
+	init_rss_vec(rss);
 	mmun_start = vma->vm_start;
 	mmun_end = vma->vm_end;
 	if (cow)
@@ -2797,6 +2799,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			get_page(ptepage);
 			page_dup_rmap(ptepage);
 			set_huge_pte_at(dst, addr, dst_pte, entry);
+			rss[MM_HUGETLBPAGES] += pages_per_huge_page(h);
 		}
 		spin_unlock(src_ptl);
 		spin_unlock(dst_ptl);
@@ -2805,6 +2808,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	if (cow)
 		mmu_notifier_invalidate_range_end(src, mmun_start, mmun_end);
 
+	add_mm_rss_vec(dst, rss);
 	return ret;
 }
 
@@ -2823,6 +2827,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	unsigned long sz = huge_page_size(h);
 	const unsigned long mmun_start = start;	/* For mmu_notifiers */
 	const unsigned long mmun_end   = end;	/* For mmu_notifiers */
+	int rss[NR_MM_COUNTERS];
 
 	WARN_ON(!is_vm_hugetlb_page(vma));
 	BUG_ON(start & ~huge_page_mask(h));
@@ -2832,6 +2837,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	address = start;
 again:
+	init_rss_vec(rss);
 	for (; address < end; address += sz) {
 		ptep = huge_pte_offset(mm, address);
 		if (!ptep)
@@ -2877,6 +2883,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
 
+		rss[MM_HUGETLBPAGES] -= pages_per_huge_page(h);
 		page_remove_rmap(page);
 		force_flush = !__tlb_remove_page(tlb, page);
 		if (force_flush) {
@@ -2892,6 +2899,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 unlock:
 		spin_unlock(ptl);
 	}
+	add_mm_rss_vec(mm, rss);
 	/*
 	 * mmu_gather ran out of room to batch pages, we break out of
 	 * the PTE lock to avoid doing the potential expensive TLB invalidate
@@ -3261,6 +3269,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 				&& (vma->vm_flags & VM_SHARED)));
 	set_huge_pte_at(mm, address, ptep, new_pte);
 
+	mod_hugetlb_rss(mm, pages_per_huge_page(h));
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 		/* Optimization, do the COW without a second fault */
 		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
mm/memory.c +2 -2
index 388dcf9aa283..e09b53da2733 100644
@@ -620,12 +620,12 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 	return 0;
 }
 
-static inline void init_rss_vec(int *rss)
+inline void init_rss_vec(int *rss)
 {
 	memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
 }
 
-static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
 {
 	int i;
 
mm/rmap.c +3 -1
index 171b68768df1..78e77b0ea3c3 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			mod_hugetlb_rss(mm, -(1 << compound_order(page)));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#16 lore raw

v2 cover hugetlb: display per-process/per-vma usage

In reply to Naoya Horiguchi

I wrote patches to export hugetlb usage info via /proc/pid/{smaps,status}. In this version, I added patch 2 for /proc/pid/status to deal with the inconsistency concern from David (thanks for the comment).

Thanks,
Naoya Horiguchi
---
Summary:

Naoya Horiguchi (2):
smaps: fill missing fields for vma(VM_HUGETLB)
mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

 fs/proc/task_mmu.c       | 32 +++++++++++++++++++++++++++++++-
 include/linux/hugetlb.h  | 18 ++++++++++++++++++
 include/linux/mm.h       |  3 +++
 include/linux/mm_types.h |  3 +++
 mm/hugetlb.c             |  9 +++++++++
 mm/memory.c              |  4 ++--
 mm/rmap.c                |  4 +++-
 7 files changed, 69 insertions(+), 4 deletions(-)���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#17 lore raw

PATCH v2 1/2 smaps: fill missing fields for vma(VM_HUGETLB)

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
 fs/proc/task_mmu.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
fs/proc/task_mmu.c +27 -0
index ca1e091881d4..c7218603306d 100644
@@ -610,12 +610,39 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		smaps_account(mss, page, huge_page_size(hstate_vma(vma)),
+			      pte_young(*pte), pte_dirty(*pte));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
maintainer
#18 lore raw

Re: [PATCH v2 1/2] smaps: fill missing fields for vma(VM_HUGETLB)

Quoted 33 lines · On Fri, 7 Aug 2015 07:24:50 +0000 Naoya Horiguchi <[email protected]>…

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB
Quoted 7 lines

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Is there something we can say about this in
Documentation/filesystems/proc.txt?

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

maintainer
#23 lore raw

Re: [PATCH v2 2/2] mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

In reply to Naoya Horiguchi
Quoted 8 lines · On Fri, 7 Aug 2015 07:24:50 +0000 Naoya Horiguchi <[email protected]>…

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/pid/status.

This patch shouldn't change the OOM behavior (so hugetlb usage is ignored as is now,) which I guess is fine until we have some strong reason to do it.

A procfs change triggers a documentation change. Always, please. Documentation/filesystems/proc.txt is the place.

include/linux/hugetlb.h static inline spinlock_t *huge_pte_lockptr(struct hstate *h, · line 524

Quoted 10 lines

...

include/linux/hugetlb.h +3 -0
@@ -504,6 +519,9 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+#define get_hugetlb_rss(mm)	0
+#define mod_hugetlb_rss(mm, value)	do {} while (0)

I don't think these have to be macros? inline functions are nicer in several ways: more readable, more likely to be documented, can prevent unused variable warnings.

Quoted 12 lines
include/linux/hugetlb.h +0 -0
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
 
...
mm/memory.c +0 -0
@@ -620,12 +620,12 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 	return 0;
 }
 

mm/memory.c int __pte_alloc_kernel(pmd_t *pmd, unsigned long address) · line 630

Quoted 10 lines
mm/memory.c +2 -2
-static inline void init_rss_vec(int *rss)
+inline void init_rss_vec(int *rss)
 {
 	memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
 }
 
-static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
 {
 	int i;

The inlines are a bit odd, but this does save ~10 bytes in memory.o for some reason.

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

#25 lore raw

PATCH v3 1/3 smaps: fill missing fields for vma(VM_HUGETLB)

In reply to Naoya Horiguchi

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
 fs/proc/task_mmu.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
fs/proc/task_mmu.c +27 -0
index ca1e091881d4..c7218603306d 100644
@@ -610,12 +610,39 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		smaps_account(mss, page, huge_page_size(hstate_vma(vma)),
+			      pte_young(*pte), pte_dirty(*pte));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#26 lore raw

PATCH v3 2/3 mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

In reply to Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/pid/status.

This patch shouldn't change the OOM behavior (so hugetlb usage is ignored as is now,) which I guess is fine until we have some strong reason to do it.

---
v2 -> v3:
- use inline functions instead of macros for !CONFIG_HUGETLB_PAGE

---
 fs/proc/task_mmu.c       |  5 ++++-
 include/linux/hugetlb.h  | 24 ++++++++++++++++++++++++
 include/linux/mm.h       |  3 +++
 include/linux/mm_types.h |  3 +++
 mm/hugetlb.c             |  9 +++++++++
 mm/memory.c              |  4 ++--
 mm/rmap.c                |  4 +++-
 7 files changed, 48 insertions(+), 4 deletions(-)
fs/proc/task_mmu.c +4 -1
index c7218603306d..f181f56fcce2 100644
@@ -22,7 +22,7 @@
 void task_mem(struct seq_file *m, struct mm_struct *mm)
 {
 	unsigned long data, text, lib, swap, ptes, pmds;
-	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss, hugetlb_rss;
 
 	/*
 	 * Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -37,6 +37,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 	hiwater_rss = total_rss = get_mm_rss(mm);
 	if (hiwater_rss < mm->hiwater_rss)
 		hiwater_rss = mm->hiwater_rss;
+	hugetlb_rss = get_hugetlb_rss(mm);
 
 	data = mm->total_vm - mm->shared_vm - mm->stack_vm;
 	text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
@@ -51,6 +52,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		"VmPin:\t%8lu kB\n"
 		"VmHWM:\t%8lu kB\n"
 		"VmRSS:\t%8lu kB\n"
+		"VmHugetlbRSS:\t%8lu kB\n"
 		"VmData:\t%8lu kB\n"
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
@@ -64,6 +66,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		mm->pinned_vm << (PAGE_SHIFT-10),
 		hiwater_rss << (PAGE_SHIFT-10),
 		total_rss << (PAGE_SHIFT-10),
+		hugetlb_rss << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
 		ptes >> 10,
include/linux/hugetlb.h +24 -0
index d891f949466a..fa956d94cacb 100644
@@ -469,6 +469,21 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+/*
+ * This simple wrappers are to hide MM_HUGETLBPAGES from outside hugetlbfs
+ * subsystem. The counter MM_HUGETLBPAGES is maintained in page unit basis,
+ * so it changes by 512 for example if a 2MB hugepage is mapped or unmapped.
+ */
+static inline int get_hugetlb_rss(struct mm_struct *mm)
+{
+	return get_mm_counter(mm, MM_HUGETLBPAGES);
+}
+
+static inline void mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+	add_mm_counter(mm, MM_HUGETLBPAGES, value);
+}
+
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +519,15 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline get_hugetlb_rss(struct mm_struct *mm)
+{
+	return 0;
+}
+
+static inline mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm.h +3 -0
index 2e872f92dbac..9218a8856483 100644
@@ -1355,6 +1355,9 @@ static inline void sync_mm_rss(struct mm_struct *mm)
 }
 #endif
 
+extern inline void init_rss_vec(int *rss);
+extern inline void add_mm_rss_vec(struct mm_struct *mm, int *rss);
+
 int vma_wants_writenotify(struct vm_area_struct *vma);
 
 extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
include/linux/mm_types.h +3 -0
index 0038ac7466fd..887b43ba5a18 100644
@@ -348,6 +348,9 @@ enum {
 	MM_FILEPAGES,
 	MM_ANONPAGES,
 	MM_SWAPENTS,
+#ifdef CONFIG_HUGETLB_PAGE
+	MM_HUGETLBPAGES,
+#endif
 	NR_MM_COUNTERS
 };
 
mm/hugetlb.c +9 -0
index a8c3087089d8..12e5e7d3b60f 100644
@@ -2743,9 +2743,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	unsigned long mmun_start;	/* For mmu_notifiers */
 	unsigned long mmun_end;		/* For mmu_notifiers */
 	int ret = 0;
+	int rss[NR_MM_COUNTERS];
 
 	cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 
+	init_rss_vec(rss);
 	mmun_start = vma->vm_start;
 	mmun_end = vma->vm_end;
 	if (cow)
@@ -2797,6 +2799,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			get_page(ptepage);
 			page_dup_rmap(ptepage);
 			set_huge_pte_at(dst, addr, dst_pte, entry);
+			rss[MM_HUGETLBPAGES] += pages_per_huge_page(h);
 		}
 		spin_unlock(src_ptl);
 		spin_unlock(dst_ptl);
@@ -2805,6 +2808,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	if (cow)
 		mmu_notifier_invalidate_range_end(src, mmun_start, mmun_end);
 
+	add_mm_rss_vec(dst, rss);
 	return ret;
 }
 
@@ -2823,6 +2827,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	unsigned long sz = huge_page_size(h);
 	const unsigned long mmun_start = start;	/* For mmu_notifiers */
 	const unsigned long mmun_end   = end;	/* For mmu_notifiers */
+	int rss[NR_MM_COUNTERS];
 
 	WARN_ON(!is_vm_hugetlb_page(vma));
 	BUG_ON(start & ~huge_page_mask(h));
@@ -2832,6 +2837,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	address = start;
 again:
+	init_rss_vec(rss);
 	for (; address < end; address += sz) {
 		ptep = huge_pte_offset(mm, address);
 		if (!ptep)
@@ -2877,6 +2883,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
 
+		rss[MM_HUGETLBPAGES] -= pages_per_huge_page(h);
 		page_remove_rmap(page);
 		force_flush = !__tlb_remove_page(tlb, page);
 		if (force_flush) {
@@ -2892,6 +2899,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 unlock:
 		spin_unlock(ptl);
 	}
+	add_mm_rss_vec(mm, rss);
 	/*
 	 * mmu_gather ran out of room to batch pages, we break out of
 	 * the PTE lock to avoid doing the potential expensive TLB invalidate
@@ -3261,6 +3269,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 				&& (vma->vm_flags & VM_SHARED)));
 	set_huge_pte_at(mm, address, ptep, new_pte);
 
+	mod_hugetlb_rss(mm, pages_per_huge_page(h));
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 		/* Optimization, do the COW without a second fault */
 		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
mm/memory.c +2 -2
index 388dcf9aa283..e09b53da2733 100644
@@ -620,12 +620,12 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 	return 0;
 }
 
-static inline void init_rss_vec(int *rss)
+inline void init_rss_vec(int *rss)
 {
 	memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
 }
 
-static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
 {
 	int i;
 
mm/rmap.c +3 -1
index 171b68768df1..78e77b0ea3c3 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			mod_hugetlb_rss(mm, -(1 << compound_order(page)));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#28 lore raw

PATCH v3 3/3 Documentation/filesystems/proc.txt: document hugetlb RSS

In reply to Naoya Horiguchi

/proc/PID/{status,smaps} is aware of hugetlb RSS now, so let's document it.

---
 Documentation/filesystems/proc.txt | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +8 -2
index 6f7fafde0884..cb8565e150ed 100644
@@ -168,6 +168,7 @@ For example, to get the status information of a process, all you have to do is
   VmLck:         0 kB
   VmHWM:       476 kB
   VmRSS:       476 kB
+  VmHugetlbRSS:  0 kB
   VmData:      156 kB
   VmStk:        88 kB
   VmExe:        68 kB
@@ -230,6 +231,7 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmLck                       locked memory size
  VmHWM                       peak resident set size ("high water mark")
  VmRSS                       size of memory portions
+ VmHugetlbRSS                size of hugetlb memory portions
  VmData                      size of data, stack, and text segments
  VmStk                       size of data, stack, and text segments
  VmExe                       size of text segment
@@ -440,8 +442,12 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
+Since 4.3, "RSS" contains the amount of mappings for hugetlb pages. Although
+RSS of hugetlb mappings is maintained separately from normal mappings
+(displayed in "VmHugetlbRSS" field of /proc/PID/status,) /proc/PID/smaps shows
+both mappings in "RSS" field. Userspace applications clearly distinguish the
+type of mapping with 'ht' flag in "VmFlags" field.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#24 lore raw

Re: [PATCH v2 2/2] mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

In reply to Andrew Morton
Quoted 7 lines · Andrew Morton
Quoted 5 lines · On Fri, 7 Aug 2015 07:24:50 +0000 Naoya Horiguchi <[email protected]>…

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/pid/status.

Quoted 6 lines
Quoted 3 lines

This patch shouldn't change the OOM behavior (so hugetlb usage is ignored as is now,) which I guess is fine until we have some strong reason to do it.

A procfs change triggers a documentation change. Always, please. Documentation/filesystems/proc.txt is the place.

OK, I'll do this.

Quoted 14 lines

include/linux/hugetlb.h static inline spinlock_t *huge_pte_lockptr(struct hstate *h, · line 524

Quoted 10 lines

...

include/linux/hugetlb.h +3 -0
@@ -504,6 +519,9 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+#define get_hugetlb_rss(mm)	0
+#define mod_hugetlb_rss(mm, value)	do {} while (0)

I don't think these have to be macros? inline functions are nicer in several ways: more readable, more likely to be documented, can prevent unused variable warnings.

Right, I'll use inline functions.

Quoted 18 lines
Quoted 18 lines
include/linux/hugetlb.h +0 -0
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
 
...
mm/memory.c +1 -1
@@ -620,12 +620,12 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 	return 0;
 }
 
-static inline void init_rss_vec(int *rss)
+inline void init_rss_vec(int *rss)
 {
 	memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
 }
 
Quoted 7 lines

mm/memory.c int __pte_alloc_kernel(pmd_t *pmd, unsigned long address) · line 630

Quoted 4 lines
mm/memory.c +1 -1
-static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
 {
 	int i;

The inlines are a bit odd, but this does save ~10 bytes in memory.o for some reason.

so I'll keep going with this.

Thanks,
Naoya Horiguchi���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#27 lore raw

Re: [PATCH v3 2/3] mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

In reply to Naoya Horiguchi
Quoted 6 lines
(quoted diff) +2 -0
@@ -504,6 +519,15 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline get_hugetlb_rss(struct mm_struct *mm)

Review static inline spinlock_t *huge_pte_lockptr(struct hstate *h, · line 533

Quoted 10 lines
(quoted diff) +7 -0
+{
+	return 0;
+}
+
+static inline mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,

sorry for my silly mistake, this doesn't build.
Let me resend this.

Thanks,
Naoya Horiguchi
---
From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] mm: hugetlb: add VmHugetlbRSS: field in /proc/pid/status

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/pid/status.

This patch shouldn't change the OOM behavior (so hugetlb usage is ignored as is now,) which I guess is fine until we have some strong reason to do it.

---
v2 -> v3:
- use inline functions instead of macros for !CONFIG_HUGETLB_PAGE

---
 fs/proc/task_mmu.c       |  5 ++++-
 include/linux/hugetlb.h  | 24 ++++++++++++++++++++++++
 include/linux/mm.h       |  3 +++
 include/linux/mm_types.h |  3 +++
 mm/hugetlb.c             |  9 +++++++++
 mm/memory.c              |  4 ++--
 mm/rmap.c                |  4 +++-
 7 files changed, 48 insertions(+), 4 deletions(-)
fs/proc/task_mmu.c +4 -1
index c7218603306d..f181f56fcce2 100644
@@ -22,7 +22,7 @@
 void task_mem(struct seq_file *m, struct mm_struct *mm)
 {
 	unsigned long data, text, lib, swap, ptes, pmds;
-	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+	unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss, hugetlb_rss;
 
 	/*
 	 * Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -37,6 +37,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 	hiwater_rss = total_rss = get_mm_rss(mm);
 	if (hiwater_rss < mm->hiwater_rss)
 		hiwater_rss = mm->hiwater_rss;
+	hugetlb_rss = get_hugetlb_rss(mm);
 
 	data = mm->total_vm - mm->shared_vm - mm->stack_vm;
 	text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
@@ -51,6 +52,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		"VmPin:\t%8lu kB\n"
 		"VmHWM:\t%8lu kB\n"
 		"VmRSS:\t%8lu kB\n"
+		"VmHugetlbRSS:\t%8lu kB\n"
 		"VmData:\t%8lu kB\n"
 		"VmStk:\t%8lu kB\n"
 		"VmExe:\t%8lu kB\n"
@@ -64,6 +66,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		mm->pinned_vm << (PAGE_SHIFT-10),
 		hiwater_rss << (PAGE_SHIFT-10),
 		total_rss << (PAGE_SHIFT-10),
+		hugetlb_rss << (PAGE_SHIFT-10),
 		data << (PAGE_SHIFT-10),
 		mm->stack_vm << (PAGE_SHIFT-10), text, lib,
 		ptes >> 10,
include/linux/hugetlb.h +24 -0
index d891f949466a..8c72e935bda8 100644
@@ -469,6 +469,21 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+/*
+ * This simple wrappers are to hide MM_HUGETLBPAGES from outside hugetlbfs
+ * subsystem. The counter MM_HUGETLBPAGES is maintained in page unit basis,
+ * so it changes by 512 for example if a 2MB hugepage is mapped or unmapped.
+ */
+static inline int get_hugetlb_rss(struct mm_struct *mm)
+{
+	return get_mm_counter(mm, MM_HUGETLBPAGES);
+}
+
+static inline void mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+	add_mm_counter(mm, MM_HUGETLBPAGES, value);
+}
+
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +519,15 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline int get_hugetlb_rss(struct mm_struct *mm)
+{
+	return 0;
+}
+
+static inline void mod_hugetlb_rss(struct mm_struct *mm, long value)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm.h +3 -0
index 2e872f92dbac..9218a8856483 100644
@@ -1355,6 +1355,9 @@ static inline void sync_mm_rss(struct mm_struct *mm)
 }
 #endif
 
+extern inline void init_rss_vec(int *rss);
+extern inline void add_mm_rss_vec(struct mm_struct *mm, int *rss);
+
 int vma_wants_writenotify(struct vm_area_struct *vma);
 
 extern pte_t *__get_locked_pte(struct mm_struct *mm, unsigned long addr,
include/linux/mm_types.h +3 -0
index 0038ac7466fd..887b43ba5a18 100644
@@ -348,6 +348,9 @@ enum {
 	MM_FILEPAGES,
 	MM_ANONPAGES,
 	MM_SWAPENTS,
+#ifdef CONFIG_HUGETLB_PAGE
+	MM_HUGETLBPAGES,
+#endif
 	NR_MM_COUNTERS
 };
 
mm/hugetlb.c +9 -0
index a8c3087089d8..12e5e7d3b60f 100644
@@ -2743,9 +2743,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	unsigned long mmun_start;	/* For mmu_notifiers */
 	unsigned long mmun_end;		/* For mmu_notifiers */
 	int ret = 0;
+	int rss[NR_MM_COUNTERS];
 
 	cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 
+	init_rss_vec(rss);
 	mmun_start = vma->vm_start;
 	mmun_end = vma->vm_end;
 	if (cow)
@@ -2797,6 +2799,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			get_page(ptepage);
 			page_dup_rmap(ptepage);
 			set_huge_pte_at(dst, addr, dst_pte, entry);
+			rss[MM_HUGETLBPAGES] += pages_per_huge_page(h);
 		}
 		spin_unlock(src_ptl);
 		spin_unlock(dst_ptl);
@@ -2805,6 +2808,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 	if (cow)
 		mmu_notifier_invalidate_range_end(src, mmun_start, mmun_end);
 
+	add_mm_rss_vec(dst, rss);
 	return ret;
 }
 
@@ -2823,6 +2827,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	unsigned long sz = huge_page_size(h);
 	const unsigned long mmun_start = start;	/* For mmu_notifiers */
 	const unsigned long mmun_end   = end;	/* For mmu_notifiers */
+	int rss[NR_MM_COUNTERS];
 
 	WARN_ON(!is_vm_hugetlb_page(vma));
 	BUG_ON(start & ~huge_page_mask(h));
@@ -2832,6 +2837,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	address = start;
 again:
+	init_rss_vec(rss);
 	for (; address < end; address += sz) {
 		ptep = huge_pte_offset(mm, address);
 		if (!ptep)
@@ -2877,6 +2883,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
 
+		rss[MM_HUGETLBPAGES] -= pages_per_huge_page(h);
 		page_remove_rmap(page);
 		force_flush = !__tlb_remove_page(tlb, page);
 		if (force_flush) {
@@ -2892,6 +2899,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 unlock:
 		spin_unlock(ptl);
 	}
+	add_mm_rss_vec(mm, rss);
 	/*
 	 * mmu_gather ran out of room to batch pages, we break out of
 	 * the PTE lock to avoid doing the potential expensive TLB invalidate
@@ -3261,6 +3269,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 				&& (vma->vm_flags & VM_SHARED)));
 	set_huge_pte_at(mm, address, ptep, new_pte);
 
+	mod_hugetlb_rss(mm, pages_per_huge_page(h));
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 		/* Optimization, do the COW without a second fault */
 		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
mm/memory.c +2 -2
index 388dcf9aa283..e09b53da2733 100644
@@ -620,12 +620,12 @@ int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 	return 0;
 }
 
-static inline void init_rss_vec(int *rss)
+inline void init_rss_vec(int *rss)
 {
 	memset(rss, 0, sizeof(int) * NR_MM_COUNTERS);
 }
 
-static inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
+inline void add_mm_rss_vec(struct mm_struct *mm, int *rss)
 {
 	int i;
 
mm/rmap.c +3 -1
index 171b68768df1..78e77b0ea3c3 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			mod_hugetlb_rss(mm, -(1 << compound_order(page)));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 4 lines
2.4.3


���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#19 lore raw

Re: [PATCH v2 1/2] smaps: fill missing fields for vma(VM_HUGETLB)

In reply to Naoya Horiguchi
Quoted 33 lines · Naoya Horiguchi

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB
Quoted 7 lines

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

I think this will lead to breakage, unfortunately, specifically for users who are concerned with resource management.

An example: we use memcg hierarchies to charge memory for individual jobs, specific users, and system overhead. Memcg is a cgroup, so this is done for an aggregate of processes, and we often have to monitor their memory usage. Each process isn't assigned to its own memcg, and I don't believe common users of memcg assign individual processes to their own memcgs.

When a memcg is out of memory, we need to track the memory usage of processes attached to its memcg hierarchy to determine what is unexpected, either as a result of a new rollout or because of a memory leak. To do that, we use the rss exported by smaps that is now changed with this patch. By using smaps rather than /proc/pid/status, we can report where memory usage is unexpected.

This would cause our process that manages all memcgs on our systems to break. Perhaps I haven't been as convincing in my previous messages of this, but it's quite an obvious userspace regression.

This memory was not included in rss originally because memory in the hugetlb persistent pool is always resident. Unmapping the memory does not free memory. For this reason, hugetlb memory has always been treated as its own type of memory.

It would have been arguable back when hugetlbfs was introduced whether it should be included. I'm afraid the ship has sailed on that since a decade has past and it would cause userspace to break if existing metrics are used that already have cleared defined semantics.

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

#29 lore raw

Re: [PATCH v3 3/3] Documentation/filesystems/proc.txt: document hugetlb RSS

In reply to Naoya Horiguchi
Quoted 25 lines · Naoya Horiguchi
Documentation/filesystems/proc.txt +2 -1
index 6f7fafde0884..cb8565e150ed 100644
@@ -168,6 +168,7 @@ For example, to get the status information of a process, all you have to do is
   VmLck:         0 kB
   VmHWM:       476 kB
   VmRSS:       476 kB
+  VmHugetlbRSS:  0 kB
   VmData:      156 kB
   VmStk:        88 kB
   VmExe:        68 kB
@@ -230,6 +231,7 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmLck                       locked memory size
  VmHWM                       peak resident set size ("high water mark")
  VmRSS                       size of memory portions
+ VmHugetlbRSS                size of hugetlb memory portions
  VmData                      size of data, stack, and text segments
  VmStk                       size of data, stack, and text segments
  VmExe                       size of text segment
@@ -440,8 +442,12 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 453

Quoted 10 lines
Documentation/filesystems/proc.txt +6 -1
-swap.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
+Since 4.3, "RSS" contains the amount of mappings for hugetlb pages. Although
+RSS of hugetlb mappings is maintained separately from normal mappings
+(displayed in "VmHugetlbRSS" field of /proc/PID/status,) /proc/PID/smaps shows
+both mappings in "RSS" field. Userspace applications clearly distinguish the
+type of mapping with 'ht' flag in "VmFlags" field.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded

My objection to adding hugetlb memory to the RSS field of /proc/pid/smaps still stands and can be addressed in the thread of the first patch. Since this includes wording that describes that change, then the objection would also cover that.

With regard to adding VmHugetlbRSS, I think the change is fine, and I appreciate that you call it VmHugetlbRSS and not VmHugeRSS since that would be confused with thp.

My only concern regarding VmHugetlbRSS would be extendability and whether we will eventually, or even today, want to differentiate between various hugetlb page sizes. For example, if 1GB hugetlb pages on x86 are a precious resource, then how do I determine which process has mapped it rather than 512 2MB hugetlb pages?

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

#20 lore raw

Re: [PATCH v2 1/2] smaps: fill missing fields for vma(VM_HUGETLB)

In reply to David Rientjes
Quoted 59 lines · David Rientjes
Quoted 33 lines · Naoya Horiguchi

Currently smaps reports many zero fields for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. This patch enables these fields by introducing smaps_hugetlb_range().

before patch:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
  Swap:                  0 kB

KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

after patch:

  Size:              20480 kB
  Rss:               18432 kB
  Pss:               18432 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:     18432 kB
  Referenced:        18432 kB
  Anonymous:         18432 kB
Quoted 7 lines

AnonHugePages: 0 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

I think this will lead to breakage, unfortunately, specifically for users who are concerned with resource management.

An example: we use memcg hierarchies to charge memory for individual jobs, specific users, and system overhead. Memcg is a cgroup, so this is done for an aggregate of processes, and we often have to monitor their memory usage. Each process isn't assigned to its own memcg, and I don't believe common users of memcg assign individual processes to their own memcgs.

When a memcg is out of memory, we need to track the memory usage of processes attached to its memcg hierarchy to determine what is unexpected, either as a result of a new rollout or because of a memory leak. To do that, we use the rss exported by smaps that is now changed with this patch. By using smaps rather than /proc/pid/status, we can report where memory usage is unexpected.

Quoted 3 lines

This would cause our process that manages all memcgs on our systems to break. Perhaps I haven't been as convincing in my previous messages of this, but it's quite an obvious userspace regression.

OK, this version assumes that userspace distinguishes vma(VM_HUGETLB) with "VmFlags" field, which is unrealistic. So I'll keep all existing fields untouched by introducing hugetlb usage info.

Quoted 4 lines

This memory was not included in rss originally because memory in the hugetlb persistent pool is always resident. Unmapping the memory does not free memory. For this reason, hugetlb memory has always been treated as its own type of memory.

Right, so it might be better not to use the word "RSS" for hugetlb, maybe something like "HugetlbPages:" seems better to me.

Thanks,
Naoya Horiguchi

Quoted 4 lines

It would have been arguable back when hugetlbfs was introduced whether it
should be included. I'm afraid the ship has sailed on that since a decade
has past and it would cause userspace to break if existing metrics are
used that already have cleared defined semantics.���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#21 lore raw

Re: [PATCH v2 1/2] smaps: fill missing fields for vma(VM_HUGETLB)

Quoted 8 lines · Naoya Horiguchi
Quoted 4 lines

This memory was not included in rss originally because memory in the hugetlb persistent pool is always resident. Unmapping the memory does not free memory. For this reason, hugetlb memory has always been treated as its own type of memory.

Right, so it might be better not to use the word "RSS" for hugetlb, maybe something like "HugetlbPages:" seems better to me.

When the pagesize is also specified, as it is in smaps, I think this would be the best option. Note that we can't distinguish between variable hugetlb sizes with VmFlags alone.

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

#30 lore raw

Re: [PATCH v3 3/3] Documentation/filesystems/proc.txt: document hugetlb RSS

In reply to David Rientjes
Quoted 35 lines · David Rientjes
Quoted 33 lines · Naoya Horiguchi
Documentation/filesystems/proc.txt +8 -2
index 6f7fafde0884..cb8565e150ed 100644
@@ -168,6 +168,7 @@ For example, to get the status information of a process, all you have to do is
   VmLck:         0 kB
   VmHWM:       476 kB
   VmRSS:       476 kB
+  VmHugetlbRSS:  0 kB
   VmData:      156 kB
   VmStk:        88 kB
   VmExe:        68 kB
@@ -230,6 +231,7 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmLck                       locked memory size
  VmHWM                       peak resident set size ("high water mark")
  VmRSS                       size of memory portions
+ VmHugetlbRSS                size of hugetlb memory portions
  VmData                      size of data, stack, and text segments
  VmStk                       size of data, stack, and text segments
  VmExe                       size of text segment
@@ -440,8 +442,12 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
+Since 4.3, "RSS" contains the amount of mappings for hugetlb pages. Although
+RSS of hugetlb mappings is maintained separately from normal mappings
+(displayed in "VmHugetlbRSS" field of /proc/PID/status,) /proc/PID/smaps shows
+both mappings in "RSS" field. Userspace applications clearly distinguish the
+type of mapping with 'ht' flag in "VmFlags" field.
 
Quoted 7 lines

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 453

Quoted 2 lines
Documentation/filesystems/proc.txt +0 -0
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded

My objection to adding hugetlb memory to the RSS field of /proc/pid/smaps still stands and can be addressed in the thread of the first patch. Since this includes wording that describes that change, then the objection would also cover that.

OK, I'll update this in accordance with the change on the first patch.

Quoted 3 lines

With regard to adding VmHugetlbRSS, I think the change is fine, and I appreciate that you call it VmHugetlbRSS and not VmHugeRSS since that would be confused with thp.

I plan to rename the field, then the new name will/should be unconfusing between thp and hugetlb.

Quoted 5 lines

My only concern regarding VmHugetlbRSS would be extendability and whether we will eventually, or even today, want to differentiate between various hugetlb page sizes. For example, if 1GB hugetlb pages on x86 are a precious resource, then how do I determine which process has mapped it rather than 512 2MB hugetlb pages?

"KernelPageSize" field in /proc/PID/smaps is aware of hugetlb page sizes, so I expected userspace to detect the size itself. But /proc/PID/status shows only proccess-wide info, so userspace applications must read both of these files to know the usage per hugepage size, which might be inconvenient.

One idea is to show the new field like "VmHugetlbRSS: 2x512kB 1x1GB" for both of /proc/PID/{status,smaps}, which passes the full hugetlb info in a single line so easier to parse and process. Or some other fields shows in "kB", so "VmHugetlbRSS: 1052672 kB (2x512kB 1x1GB)" is possible for human readability.

Thank you very much for the feedback, I'll repost soon, but any additional comment is appreciated.

Naoya���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#32 lore raw

PATCH v4 2/2 mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10x2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

HugetlbPages: 1069056 kB (1x1048576kB 10x2048kB)

, so you can easily know how many hugepages in which pagesize are used by a process.

---
v3 -> v4:
- rename field (VmHugetlbRSS is not the best name)
- introduce struct hugetlb_usage in struct mm_struct (no invasion to struct mm_rss_stat)
- introduce hugetlb_report_usage()
- merged documentation update

v2 -> v3:
- use inline functions instead of macros for !CONFIG_HUGETLB_PAGE

---
 Documentation/filesystems/proc.txt |  3 +++
 fs/proc/task_mmu.c                 |  1 +
 include/linux/hugetlb.h            | 20 ++++++++++++++++++++
 include/linux/mm_types.h           | 10 ++++++++++
 mm/hugetlb.c                       | 27 +++++++++++++++++++++++++++
 mm/rmap.c                          |  4 +++-
 6 files changed, 64 insertions(+), 1 deletion(-)
Documentation/filesystems/proc.txt +3 -0
index 22e40211ef64..e92a4a91fc99 100644
@@ -174,6 +174,7 @@ For example, to get the status information of a process, all you have to do is
   VmLib:      1412 kB
   VmPTE:        20 kb
   VmSwap:        0 kB
+  HugetlbPages:          0 kB (0x2048kB)
   Threads:        1
   SigQ:   0/28578
   SigPnd: 0000000000000000
@@ -237,6 +238,8 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmPTE                       size of page table entries
  VmPMD                       size of second level page tables
  VmSwap                      size of swap usage (the number of referred swapents)
+ HugetlbPages                size of hugetlb memory portions (with additional info
+                             about number of mapped hugepages for each page size)
  Threads                     number of threads
  SigQ                        number of signals queued/max. number for queue
  SigPnd                      bitmap of pending signals for the thread
fs/proc/task_mmu.c +1 -0
index 2c37938b82ee..b3cf7fa9ef6c 100644
@@ -69,6 +69,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		ptes >> 10,
 		pmds >> 10,
 		swap << (PAGE_SHIFT-10));
+	hugetlb_report_usage(m, mm);
 }
 
 unsigned long task_vsize(struct mm_struct *mm)
include/linux/hugetlb.h +20 -0
index d891f949466a..64aa4db01f48 100644
@@ -469,6 +469,18 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
+
+static inline void inc_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	atomic_long_inc(&mm->hugetlb_usage.count[hstate_index(h)]);
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	atomic_long_dec(&mm->hugetlb_usage.count[hstate_index(h)]);
+}
+
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +516,14 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
+{
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm_types.h +10 -0
index 0038ac7466fd..e95c5fe1eb7d 100644
@@ -364,6 +364,12 @@ struct mm_rss_stat {
 	atomic_long_t count[NR_MM_COUNTERS];
 };
 
+#ifdef CONFIG_HUGETLB_PAGE
+struct hugetlb_usage {
+	atomic_long_t count[HUGE_MAX_HSTATE];
+};
+#endif
+
 struct kioctx_table;
 struct mm_struct {
 	struct vm_area_struct *mmap;		/* list of VMAs */
@@ -484,6 +490,10 @@ struct mm_struct {
 	/* address of the bounds directory */
 	void __user *bd_addr;
 #endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+	struct hugetlb_usage hugetlb_usage;
+#endif
 };
 
 static inline void mm_init_cpumask(struct mm_struct *mm)
mm/hugetlb.c +27 -0
index a8c3087089d8..b890431d0763 100644
@@ -2562,6 +2562,30 @@ void hugetlb_show_meminfo(void)
 				1UL << (huge_page_order(h) + PAGE_SHIFT - 10));
 }
 
+void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm)
+{
+	int i;
+	unsigned long total_usage = 0;
+
+	for (i = 0; i < HUGE_MAX_HSTATE; i++) {
+		total_usage += atomic_long_read(&mm->hugetlb_usage.count[i]) *
+			(huge_page_size(&hstates[i]) >> 10);
+	}
+
+	seq_printf(m, "HugetlbPages:\t%8lu kB (", total_usage);
+	for (i = 0; i < HUGE_MAX_HSTATE; i++) {
+		if (huge_page_order(&hstates[i]) == 0)
+			break;
+		if (i > 0)
+			seq_puts(m, " ");
+
+		seq_printf(m, "%ldx%dkB",
+			atomic_long_read(&mm->hugetlb_usage.count[i]),
+			huge_page_size(&hstates[i]) >> 10);
+	}
+	seq_puts(m, ")\n");
+}
+
 /* Return the number pages of memory we physically have, in PAGE_SIZE units. */
 unsigned long hugetlb_total_pages(void)
 {
@@ -2797,6 +2821,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			get_page(ptepage);
 			page_dup_rmap(ptepage);
 			set_huge_pte_at(dst, addr, dst_pte, entry);
+			inc_hugetlb_count(dst, h);
 		}
 		spin_unlock(src_ptl);
 		spin_unlock(dst_ptl);
@@ -2877,6 +2902,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
 
+		dec_hugetlb_count(mm, h);
 		page_remove_rmap(page);
 		force_flush = !__tlb_remove_page(tlb, page);
 		if (force_flush) {
@@ -3261,6 +3287,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 				&& (vma->vm_flags & VM_SHARED)));
 	set_huge_pte_at(mm, address, ptep, new_pte);
 
+	inc_hugetlb_count(mm, h);
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 		/* Optimization, do the COW without a second fault */
 		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
mm/rmap.c +3 -1
index 171b68768df1..b33278bc4ddb 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			dec_hugetlb_count(mm, page_hstate(page));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#31 lore raw

PATCH v4 1/2 mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +5 -2
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded
fs/proc/task_mmu.c +29 -0
index ca1e091881d4..2c37938b82ee 100644
@@ -445,6 +445,7 @@ struct mem_size_stats {
 	unsigned long anonymous;
 	unsigned long anonymous_thp;
 	unsigned long swap;
+	unsigned long hugetlb;
 	u64 pss;
 };
 
@@ -610,12 +611,38 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		mss->hugetlb += huge_page_size(hstate_vma(vma));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
@@ -637,6 +664,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   "Referenced:     %8lu kB\n"
 		   "Anonymous:      %8lu kB\n"
 		   "AnonHugePages:  %8lu kB\n"
+		   "HugetlbPages:   %8lu kB\n"
 		   "Swap:           %8lu kB\n"
 		   "KernelPageSize: %8lu kB\n"
 		   "MMUPageSize:    %8lu kB\n"
@@ -651,6 +679,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   mss.referenced >> 10,
 		   mss.anonymous >> 10,
 		   mss.anonymous_thp >> 10,
+		   mss.hugetlb >> 10,
 		   mss.swap >> 10,
 		   vma_kernel_pagesize(vma) >> 10,
 		   vma_mmu_pagesize(vma) >> 10,
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Acked-by on v4 1/2
#38 lore raw

Re: [PATCH v4 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 14 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
Quoted 8 lines

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

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

#33 lore raw

Re: [PATCH v4 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Naoya Horiguchi
Quoted 13 lines · Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10x2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

Quoted 6 lines

HugetlbPages: 1069056 kB (1x1048576kB 10x2048kB)

, so you can easily know how many hugepages in which pagesize are used by a process.

I'm happy with this and thanks very much for going the extra mile and breaking the usage down by hstate size.

I'd be interested in the comments of others, though, to see if there is any reservation about the hstate size breakdown. It may actually find no current customer who is interested in parsing it. (If we keep it, I would suggest the 'x' change to '*' similar to per-order breakdowns in show_mem()). It may also be possible to add it later if a definitive usecase is presented.

But overall I'm very happy with the new addition and think it's a good solution to the problem.

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

#34 lore raw

Re: [PATCH v4 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 17 lines · David Rientjes
Quoted 15 lines · Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10x2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

HugetlbPages: 1069056 kB (1x1048576kB 10x2048kB)

Quoted 7 lines
Quoted 4 lines

, so you can easily know how many hugepages in which pagesize are used by a process.

I'm happy with this and thanks very much for going the extra mile and breaking the usage down by hstate size.

Great to hear that.

Quoted 6 lines

I'd be interested in the comments of others, though, to see if there is any reservation about the hstate size breakdown. It may actually find no current customer who is interested in parsing it. (If we keep it, I would suggest the 'x' change to '*' similar to per-order breakdowns in show_mem()). It may also be possible to add it later if a definitive usecase is presented.

I'm fine to change to '*'.

Thanks,
Naoya Horiguchi
---
From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10*2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

, so you can easily know how many hugepages in which pagesize are used by a process.

---
 Documentation/filesystems/proc.txt |  3 +++
 fs/proc/task_mmu.c                 |  1 +
 include/linux/hugetlb.h            | 20 ++++++++++++++++++++
 include/linux/mm_types.h           | 10 ++++++++++
 mm/hugetlb.c                       | 27 +++++++++++++++++++++++++++
 mm/rmap.c                          |  4 +++-
 6 files changed, 64 insertions(+), 1 deletion(-)
Documentation/filesystems/proc.txt +3 -0
index 22e40211ef64..f561fc46e41b 100644
@@ -174,6 +174,7 @@ For example, to get the status information of a process, all you have to do is
   VmLib:      1412 kB
   VmPTE:        20 kb
   VmSwap:        0 kB
+  HugetlbPages:          0 kB (0*2048kB)
   Threads:        1
   SigQ:   0/28578
   SigPnd: 0000000000000000
@@ -237,6 +238,8 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmPTE                       size of page table entries
  VmPMD                       size of second level page tables
  VmSwap                      size of swap usage (the number of referred swapents)
+ HugetlbPages                size of hugetlb memory portions (with additional info
+                             about number of mapped hugepages for each page size)
  Threads                     number of threads
  SigQ                        number of signals queued/max. number for queue
  SigPnd                      bitmap of pending signals for the thread
fs/proc/task_mmu.c +1 -0
index 2c37938b82ee..b3cf7fa9ef6c 100644
@@ -69,6 +69,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		ptes >> 10,
 		pmds >> 10,
 		swap << (PAGE_SHIFT-10));
+	hugetlb_report_usage(m, mm);
 }
 
 unsigned long task_vsize(struct mm_struct *mm)
include/linux/hugetlb.h +20 -0
index d891f949466a..64aa4db01f48 100644
@@ -469,6 +469,18 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
+
+static inline void inc_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	atomic_long_inc(&mm->hugetlb_usage.count[hstate_index(h)]);
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	atomic_long_dec(&mm->hugetlb_usage.count[hstate_index(h)]);
+}
+
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +516,14 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
+{
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm_types.h +10 -0
index 0038ac7466fd..e95c5fe1eb7d 100644
@@ -364,6 +364,12 @@ struct mm_rss_stat {
 	atomic_long_t count[NR_MM_COUNTERS];
 };
 
+#ifdef CONFIG_HUGETLB_PAGE
+struct hugetlb_usage {
+	atomic_long_t count[HUGE_MAX_HSTATE];
+};
+#endif
+
 struct kioctx_table;
 struct mm_struct {
 	struct vm_area_struct *mmap;		/* list of VMAs */
@@ -484,6 +490,10 @@ struct mm_struct {
 	/* address of the bounds directory */
 	void __user *bd_addr;
 #endif
+
+#ifdef CONFIG_HUGETLB_PAGE
+	struct hugetlb_usage hugetlb_usage;
+#endif
 };
 
 static inline void mm_init_cpumask(struct mm_struct *mm)
mm/hugetlb.c +27 -0
index a8c3087089d8..2338c9713b7a 100644
@@ -2562,6 +2562,30 @@ void hugetlb_show_meminfo(void)
 				1UL << (huge_page_order(h) + PAGE_SHIFT - 10));
 }
 
+void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm)
+{
+	int i;
+	unsigned long total_usage = 0;
+
+	for (i = 0; i < HUGE_MAX_HSTATE; i++) {
+		total_usage += atomic_long_read(&mm->hugetlb_usage.count[i]) *
+			(huge_page_size(&hstates[i]) >> 10);
+	}
+
+	seq_printf(m, "HugetlbPages:\t%8lu kB (", total_usage);
+	for (i = 0; i < HUGE_MAX_HSTATE; i++) {
+		if (huge_page_order(&hstates[i]) == 0)
+			break;
+		if (i > 0)
+			seq_puts(m, " ");
+
+		seq_printf(m, "%ld*%dkB",
+			atomic_long_read(&mm->hugetlb_usage.count[i]),
+			huge_page_size(&hstates[i]) >> 10);
+	}
+	seq_puts(m, ")\n");
+}
+
 /* Return the number pages of memory we physically have, in PAGE_SIZE units. */
 unsigned long hugetlb_total_pages(void)
 {
@@ -2797,6 +2821,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			get_page(ptepage);
 			page_dup_rmap(ptepage);
 			set_huge_pte_at(dst, addr, dst_pte, entry);
+			inc_hugetlb_count(dst, h);
 		}
 		spin_unlock(src_ptl);
 		spin_unlock(dst_ptl);
@@ -2877,6 +2902,7 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
 		if (huge_pte_dirty(pte))
 			set_page_dirty(page);
 
+		dec_hugetlb_count(mm, h);
 		page_remove_rmap(page);
 		force_flush = !__tlb_remove_page(tlb, page);
 		if (force_flush) {
@@ -3261,6 +3287,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
 				&& (vma->vm_flags & VM_SHARED)));
 	set_huge_pte_at(mm, address, ptep, new_pte);
 
+	inc_hugetlb_count(mm, h);
 	if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) {
 		/* Optimization, do the COW without a second fault */
 		ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page, ptl);
mm/rmap.c +3 -1
index 171b68768df1..b33278bc4ddb 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			dec_hugetlb_count(mm, page_hstate(page));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#36 lore raw

Re: [PATCH v4 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to David Rientjes
Quoted 7 lines · David Rientjes

I'd be interested in the comments of others, though, to see if there is any reservation about the hstate size breakdown. It may actually find no current customer who is interested in parsing it. (If we keep it, I would suggest the 'x' change to '*' similar to per-order breakdowns in show_mem()). It may also be possible to add it later if a definitive usecase is presented.

I have no interest in parsing the size breakdown today. I might change my mind tomorrow and having the extra information hurts very little, so I won't argue against it either.

Quoted 2 lines

But overall I'm very happy with the new addition and think it's a good solution to the problem.

Agreed. Thank you!

Jorn

--
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision.
-- Bertrand Russell

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

Acked-by Joern Engel
#35 lore raw

Re: [PATCH v4 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Naoya Horiguchi
Quoted 16 lines · Naoya Horiguchi

From: Naoya Horiguchi <[email protected]>
Subject: [PATCH] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10*2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

Quoted 6 lines

HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

, so you can easily know how many hugepages in which pagesize are used by a process.

Jorn

--
Computer system analysis is like child-rearing; you can do grievous damage, but you cannot ensure success."
-- Tom DeMarco

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

Acked-by Joern Engel
#39 lore raw

Re: [PATCH v4 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to David Rientjes
Quoted 23 lines · David Rientjes
Quoted 21 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Quoted 3 lines
Quoted 1 line

Jorn

--
One of my most productive days was throwing away 1000 lines of code. -- Ken Thompson.

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

#37 lore raw

Re: [PATCH v4 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to David Rientjes
Quoted 10 lines · David Rientjes

I'm happy with this and thanks very much for going the extra mile and breaking the usage down by hstate size.

I'd be interested in the comments of others, though, to see if there is any reservation about the hstate size breakdown. It may actually find no current customer who is interested in parsing it. (If we keep it, I would suggest the 'x' change to '*' similar to per-order breakdowns in show_mem()). It may also be possible to add it later if a definitive usecase is presented.

Quoted 3 lines

But overall I'm very happy with the new addition and think it's a good solution to the problem.

No objections from anybody else, so

Thanks Naoya!

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

#40 lore raw

v5 cover hugetlb: display per-process/per-vma usage

In reply to Naoya Horiguchi

The previous version had build issues in some architectures, because it required to move the definition of HUGE_MAX_HSTATE across header files in order to embed a new data structure struct hugetlb_usage into struct mm_struct. This was a hard problem to solve, so I took another approach in this version, where I add just a pointer (struct hugetlb_usage *) to struct mm_struct and dynamically allocate and link it.
This makes the changes larger, but no build issues.

Thanks,
Naoya Horiguchi
---
Summary:

Naoya Horiguchi (2):
mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps
mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

 Documentation/filesystems/proc.txt | 10 +++++++--
 fs/hugetlbfs/inode.c               | 12 ++++++++++
 fs/proc/task_mmu.c                 | 30 +++++++++++++++++++++++++
 include/linux/hugetlb.h            | 36 +++++++++++++++++++++++++++++
 include/linux/mm_types.h           |  7 ++++++
 kernel/fork.c                      |  3 +++
 mm/hugetlb.c                       | 46 ++++++++++++++++++++++++++++++++++++++
 mm/mmap.c                          |  1 +
 mm/rmap.c                          |  4 +++-
 9 files changed, 146 insertions(+), 3 deletions(-)���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#53 lore raw

PATCH v5 2/2 mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Currently there's no easy way to get per-process usage of hugetlb pages, which is inconvenient because userspace applications which use hugetlb typically want to control their processes on the basis of how much memory (including hugetlb) they use. So this patch simply provides easy access to the info via /proc/PID/status.

With this patch, for example, /proc/PID/status shows a line like this:

HugetlbPages: 20480 kB (10*2048kB)

If your system supports and enables multiple hugepage sizes, the line looks like this:

HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

, so you can easily know how many hugepages in which pagesize are used by a process.

---
v4 -> v5:
- add (struct hugetlb_usage *) to struct mm_struct
- use %lu instead of %d for seq_printf()
- introduce hugetlb_fork

v3 -> v4:
- rename field (VmHugetlbRSS is not the best name)
- introduce struct hugetlb_usage in struct mm_struct (no invasion to struct mm_rss_stat)
- introduce hugetlb_report_usage()
- merged documentation update

v2 -> v3:
- use inline functions instead of macros for !CONFIG_HUGETLB_PAGE

---
 Documentation/filesystems/proc.txt |  3 +++
 fs/hugetlbfs/inode.c               | 12 ++++++++++
 fs/proc/task_mmu.c                 |  1 +
 include/linux/hugetlb.h            | 36 +++++++++++++++++++++++++++++
 include/linux/mm_types.h           |  7 ++++++
 kernel/fork.c                      |  3 +++
 mm/hugetlb.c                       | 46 ++++++++++++++++++++++++++++++++++++++
 mm/mmap.c                          |  1 +
 mm/rmap.c                          |  4 +++-
 9 files changed, 112 insertions(+), 1 deletion(-)
Documentation/filesystems/proc.txt +3 -0
index 22e40211ef64..f561fc46e41b 100644
@@ -174,6 +174,7 @@ For example, to get the status information of a process, all you have to do is
   VmLib:      1412 kB
   VmPTE:        20 kb
   VmSwap:        0 kB
+  HugetlbPages:          0 kB (0*2048kB)
   Threads:        1
   SigQ:   0/28578
   SigPnd: 0000000000000000
@@ -237,6 +238,8 @@ Table 1-2: Contents of the status files (as of 4.1)
  VmPTE                       size of page table entries
  VmPMD                       size of second level page tables
  VmSwap                      size of swap usage (the number of referred swapents)
+ HugetlbPages                size of hugetlb memory portions (with additional info
+                             about number of mapped hugepages for each page size)
  Threads                     number of threads
  SigQ                        number of signals queued/max. number for queue
  SigPnd                      bitmap of pending signals for the thread
fs/hugetlbfs/inode.c +12 -0
index 0cf74df68617..bf6ea2645d35 100644
@@ -115,6 +115,13 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 	if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
 		return -EINVAL;
 
+	if (!vma->vm_mm->hugetlb_usage) {
+		vma->vm_mm->hugetlb_usage = kzalloc(sizeof(struct hugetlb_usage),
+							GFP_KERNEL);
+		if (!vma->vm_mm->hugetlb_usage)
+			return -ENOMEM;
+	}
+
 	vma_len = (loff_t)(vma->vm_end - vma->vm_start);
 
 	mutex_lock(&inode->i_mutex);
@@ -138,6 +145,11 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 	return ret;
 }
 
+void exit_hugetlb_mmap(struct mm_struct *mm)
+{
+	kfree(mm->hugetlb_usage);
+}
+
 /*
  * Called under down_write(mmap_sem).
  */
fs/proc/task_mmu.c +1 -0
index 2c37938b82ee..b3cf7fa9ef6c 100644
@@ -69,6 +69,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm)
 		ptes >> 10,
 		pmds >> 10,
 		swap << (PAGE_SHIFT-10));
+	hugetlb_report_usage(m, mm);
 }
 
 unsigned long task_vsize(struct mm_struct *mm)
include/linux/hugetlb.h +36 -0
index d891f949466a..db642ad0b847 100644
@@ -469,6 +469,25 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 #define hugepages_supported() (HPAGE_SHIFT != 0)
 #endif
 
+struct hugetlb_usage {
+	atomic_long_t count[HUGE_MAX_HSTATE];
+};
+
+void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
+void exit_hugetlb_mmap(struct mm_struct *mm);
+int hugetlb_fork(struct mm_struct *new, struct mm_struct *old);
+
+static inline void inc_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	VM_BUG_ON_MM(!mm->hugetlb_usage, mm);
+	atomic_long_inc(&mm->hugetlb_usage->count[hstate_index(h)]);
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+	VM_BUG_ON_MM(!mm->hugetlb_usage, mm);
+	atomic_long_dec(&mm->hugetlb_usage->count[hstate_index(h)]);
+}
 #else	/* CONFIG_HUGETLB_PAGE */
 struct hstate {};
 #define alloc_huge_page_node(h, nid) NULL
@@ -504,6 +523,23 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 {
 	return &mm->page_table_lock;
 }
+
+static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
+{
+}
+
+static inline void exit_hugetlb_mmap(struct mm_struct *mm)
+{
+}
+
+static inline int hugetlb_fork(struct mm_struct *new, struct mm_struct *old)
+{
+	return 0;
+}
+
+static inline void dec_hugetlb_count(struct mm_struct *mm, struct hstate *h)
+{
+}
 #endif	/* CONFIG_HUGETLB_PAGE */
 
 static inline spinlock_t *huge_pte_lock(struct hstate *h,
include/linux/mm_types.h +7 -0
index 0038ac7466fd..851e964ee8d6 100644
@@ -364,6 +364,10 @@ struct mm_rss_stat {
 	atomic_long_t count[NR_MM_COUNTERS];
 };
 
+#ifdef CONFIG_HUGETLB_PAGE
+struct hugetlb_usage;
+#endif
+
 struct kioctx_table;
 struct mm_struct {
 	struct vm_area_struct *mmap;		/* list of VMAs */
@@ -484,6 +488,9 @@ struct mm_struct {
 	/* address of the bounds directory */
 	void __user *bd_addr;
 #endif
+#ifdef CONFIG_HUGETLB_PAGE
+	struct hugetlb_usage *hugetlb_usage;
+#endif
 };
 
 static inline void mm_init_cpumask(struct mm_struct *mm)
kernel/fork.c +3 -0
index dbd9b8d7b7cc..d43baa91d48c 100644
@@ -425,6 +425,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
 	retval = khugepaged_fork(mm, oldmm);
 	if (retval)
 		goto out;
+	retval = hugetlb_fork(mm, oldmm);
+	if (retval)
+		goto out;
 
 	prev = NULL;
 	for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
mm/hugetlb.c +46 -0

70 lines not on this page · raw message

mm/mmap.c +1 -0
index aa632ade2be7..9d9562bc79a8 100644
@@ -2847,6 +2847,7 @@ void exit_mmap(struct mm_struct *mm)
 			nr_accounted += vma_pages(vma);
 		vma = remove_vma(vma);
 	}
+	exit_hugetlb_mmap(mm);
 	vm_unacct_memory(nr_accounted);
 }
 
mm/rmap.c +3 -1
index 171b68768df1..b33278bc4ddb 100644
@@ -1230,7 +1230,9 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
 	update_hiwater_rss(mm);
 
 	if (PageHWPoison(page) && !(flags & TTU_IGNORE_HWPOISON)) {
-		if (!PageHuge(page)) {
+		if (PageHuge(page)) {
+			dec_hugetlb_count(mm, page_hstate(page));
+		} else {
 			if (PageAnon(page))
 				dec_mm_counter(mm, MM_ANONPAGES);
 			else
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
#41 lore raw

PATCH v5 1/2 mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +5 -2
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded
fs/proc/task_mmu.c +29 -0
index ca1e091881d4..2c37938b82ee 100644
@@ -445,6 +445,7 @@ struct mem_size_stats {
 	unsigned long anonymous;
 	unsigned long anonymous_thp;
 	unsigned long swap;
+	unsigned long hugetlb;
 	u64 pss;
 };
 
@@ -610,12 +611,38 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		mss->hugetlb += huge_page_size(hstate_vma(vma));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
@@ -637,6 +664,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   "Referenced:     %8lu kB\n"
 		   "Anonymous:      %8lu kB\n"
 		   "AnonHugePages:  %8lu kB\n"
+		   "HugetlbPages:   %8lu kB\n"
 		   "Swap:           %8lu kB\n"
 		   "KernelPageSize: %8lu kB\n"
 		   "MMUPageSize:    %8lu kB\n"
@@ -651,6 +679,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   mss.referenced >> 10,
 		   mss.anonymous >> 10,
 		   mss.anonymous_thp >> 10,
+		   mss.hugetlb >> 10,
 		   mss.swap >> 10,
 		   vma_kernel_pagesize(vma) >> 10,
 		   vma_mmu_pagesize(vma) >> 10,
Signature · 2 lines
2.4.3
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Acked-by on v5 1/2
#42 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 14 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB
Quoted 6 lines

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

I have only now got to this thread. This is indeed very helpful. I would just suggest to update Documentation/filesystems/proc.txt to be explicit that Rss: doesn't count hugetlb pages for historical reasons.

Quoted 3 lines
Quoted 108 lines

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +5 -2
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
 
 "VmFlags" field deserves a separate description. This member represents the kernel
 flags associated with the particular virtual memory area in two letter encoded
fs/proc/task_mmu.c +29 -0
index ca1e091881d4..2c37938b82ee 100644
@@ -445,6 +445,7 @@ struct mem_size_stats {
 	unsigned long anonymous;
 	unsigned long anonymous_thp;
 	unsigned long swap;
+	unsigned long hugetlb;
 	u64 pss;
 };
 
@@ -610,12 +611,38 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
 	seq_putc(m, '\n');
 }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		mss->hugetlb += huge_page_size(hstate_vma(vma));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
 static int show_smap(struct seq_file *m, void *v, int is_pid)
 {
 	struct vm_area_struct *vma = v;
 	struct mem_size_stats mss;
 	struct mm_walk smaps_walk = {
 		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
 		.mm = vma->vm_mm,
 		.private = &mss,
 	};
@@ -637,6 +664,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   "Referenced:     %8lu kB\n"
 		   "Anonymous:      %8lu kB\n"
 		   "AnonHugePages:  %8lu kB\n"
+		   "HugetlbPages:   %8lu kB\n"
 		   "Swap:           %8lu kB\n"
 		   "KernelPageSize: %8lu kB\n"
 		   "MMUPageSize:    %8lu kB\n"
@@ -651,6 +679,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
 		   mss.referenced >> 10,
 		   mss.anonymous >> 10,
 		   mss.anonymous_thp >> 10,
+		   mss.hugetlb >> 10,
 		   mss.swap >> 10,
 		   vma_kernel_pagesize(vma) >> 10,
 		   vma_mmu_pagesize(vma) >> 10,
Signature · 2 lines
2.4.3
N?????r??y????b?X??ǧv?^?)޺{.n?+????{????zX????ܨ}???Ơz?&j:+v???????zZ+??+zf???h???~????i???z??w?????????&?)ߢf??^jǫy?m??@A?a???0??h???i
Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#54 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Naoya Horiguchi
Quoted 1 line · Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages,

Is this really the case after your previous patch? You have both HugetlbPages and KernelPageSize which should be sufficient no?

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

[...]

Quoted 10 lines
 Documentation/filesystems/proc.txt |  3 +++
 fs/hugetlbfs/inode.c               | 12 ++++++++++
 fs/proc/task_mmu.c                 |  1 +
 include/linux/hugetlb.h            | 36 +++++++++++++++++++++++++++++
 include/linux/mm_types.h           |  7 ++++++
 kernel/fork.c                      |  3 +++
 mm/hugetlb.c                       | 46 ++++++++++++++++++++++++++++++++++++++
 mm/mmap.c                          |  1 +
 mm/rmap.c                          |  4 +++-
 9 files changed, 112 insertions(+), 1 deletion(-)

[...]

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#55 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 11 lines · Michal Hocko
Quoted 1 line · Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages,

Is this really the case after your previous patch? You have both HugetlbPages and KernelPageSize which should be sufficient no?

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

/proc/pid/smaps requires root, /proc/pid/status doesn't.

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

#43 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Michal Hocko

T24gVGh1LCBBdWcgMjAsIDIwMTUgYXQgMTI6NDk6MjlQTSArMDIwMCwgTWljaGFsIEhvY2tvIHdy b3RlOg0KPiBPbiBUaHUgMjAtMDgtMTUgMDg6MjY6MjYsIE5hb3lhIEhvcmlndWNoaSB3cm90ZToN Cj4gPiBDdXJyZW50bHkgL3Byb2MvUElEL3NtYXBzIHByb3ZpZGVzIG5vIHVzYWdlIGluZm8gZm9y IHZtYShWTV9IVUdFVExCKSwgd2hpY2gNCj4gPiBpcyBpbmNvbnZlbmllbnQgd2hlbiB3ZSB3YW50 IHRvIGtub3cgcGVyLXRhc2sgb3IgcGVyLXZtYSBiYXNlIGh1Z2V0bGIgdXNhZ2UuDQo+ID4gVG8g c29sdmUgdGhpcywgdGhpcyBwYXRjaCBhZGRzIGEgbmV3IGxpbmUgZm9yIGh1Z2V0bGIgdXNhZ2Ug bGlrZSBiZWxvdzoNCj4gPiANCj4gPiAgIFNpemU6ICAgICAgICAgICAgICAyMDQ4MCBrQg0KPiA+ ICAgUnNzOiAgICAgICAgICAgICAgICAgICAwIGtCDQo+ID4gICBQc3M6ICAgICAgICAgICAgICAg ICAgIDAga0INCj4gPiAgIFNoYXJlZF9DbGVhbjogICAgICAgICAgMCBrQg0KPiA+ICAgU2hhcmVk X0RpcnR5OiAgICAgICAgICAwIGtCDQo+ID4gICBQcml2YXRlX0NsZWFuOiAgICAgICAgIDAga0IN Cj4gPiAgIFByaXZhdGVfRGlydHk6ICAgICAgICAgMCBrQg0KPiA+ICAgUmVmZXJlbmNlZDogICAg ICAgICAgICAwIGtCDQo+ID4gICBBbm9ueW1vdXM6ICAgICAgICAgICAgIDAga0INCj4gPiAgIEFu b25IdWdlUGFnZXM6ICAgICAgICAgMCBrQg0KPiA+ICAgSHVnZXRsYlBhZ2VzOiAgICAgIDE4NDMy IGtCDQo+ID4gICBTd2FwOiAgICAgICAgICAgICAgICAgIDAga0INCj4gPiAgIEtlcm5lbFBhZ2VT aXplOiAgICAgMjA0OCBrQg0KPiA+ICAgTU1VUGFnZVNpemU6ICAgICAgICAyMDQ4IGtCDQo+ID4g ICBMb2NrZWQ6ICAgICAgICAgICAgICAgIDAga0INCj4gPiAgIFZtRmxhZ3M6IHJkIHdyIG1yIG13 IG1lIGRlIGh0DQo+IA0KPiBJIGhhdmUgb25seSBub3cgZ290IHRvIHRoaXMgdGhyZWFkLiBUaGlz IGlzIGluZGVlZCB2ZXJ5IGhlbHBmdWwuIEkgd291bGQNCj4ganVzdCBzdWdnZXN0IHRvIHVwZGF0 ZSBEb2N1bWVudGF0aW9uL2ZpbGVzeXN0ZW1zL3Byb2MudHh0IHRvIGJlIGV4cGxpY2l0DQo+IHRo YXQgUnNzOiBkb2Vzbid0IGNvdW50IGh1Z2V0bGIgcGFnZXMgZm9yIGhpc3RvcmljYWwgcmVhc29u cy4NCg0KSSBhZ3JlZSwgSSB3YW50IHRoZSBmb2xsb3dpbmcgZGlmZiB0byBiZSBmb2xkZWQgdG8g dGhpcyBwYXRjaC4NCg0KPiAgDQo+ID4gU2lnbmVkLW9mZi1ieTogTmFveWEgSG9yaWd1Y2hpIDxu LWhvcmlndWNoaUBhaC5qcC5uZWMuY29tPg0KPiA+IEFja2VkLWJ5OiBKb2VybiBFbmdlbCA8am9l cm5AbG9nZnMub3JnPg0KPiA+IEFja2VkLWJ5OiBEYXZpZCBSaWVudGplcyA8cmllbnRqZXNAZ29v Z2xlLmNvbT4NCj4gDQo+IEFja2VkLWJ5OiBNaWNoYWwgSG9ja28gPG1ob2Nrb0BzdXNlLmN6Pg0K DQpUaGFuayB5b3UuDQpOYW95YSBIb3JpZ3VjaGkNCi0tLQ0KRnJvbTogTmFveWEgSG9yaWd1Y2hp IDxuLWhvcmlndWNoaUBhaC5qcC5uZWMuY29tPg0KRGF0ZTogRnJpLCAyMSBBdWcgMjAxNSAwODox MzozMSArMDkwMA0KU3ViamVjdDogW1BBVENIXSBEb2N1bWVudGF0aW9uL2ZpbGVzeXN0ZW1zL3By b2MudHh0OiBnaXZlIGFkZGl0aW9uYWwgY29tbWVudA0KIGFib3V0IGh1Z2V0bGIgdXNhZ2UNCg0K LS0tDQogRG9jdW1lbnRhdGlvbi9maWxlc3lzdGVtcy9wcm9jLnR4dCB8IDMgKystDQogMSBmaWxl IGNoYW5nZWQsIDIgaW5zZXJ0aW9ucygrKSwgMSBkZWxldGlvbigtKQ0KDQpkaWZmIC0tZ2l0IGEv RG9jdW1lbnRhdGlvbi9maWxlc3lzdGVtcy9wcm9jLnR4dCBiL0RvY3VtZW50YXRpb24vZmlsZXN5 c3RlbXMvcHJvYy50eHQNCmluZGV4IGY1NjFmYzQ2ZTQxYi4uYjc3NWI2ZmFhZWRhIDEwMDY0NA0K LS0tIGEvRG9jdW1lbnRhdGlvbi9maWxlc3lzdGVtcy9wcm9jLnR4dA0KKysrIGIvRG9jdW1lbnRh dGlvbi9maWxlc3lzdGVtcy9wcm9jLnR4dA0KQEAgLTQ0Niw3ICs0NDYsOCBAQCBpbmRpY2F0ZXMg dGhlIGFtb3VudCBvZiBtZW1vcnkgY3VycmVudGx5IG1hcmtlZCBhcyByZWZlcmVuY2VkIG9yIGFj Y2Vzc2VkLg0KIGEgbWFwcGluZyBhc3NvY2lhdGVkIHdpdGggYSBmaWxlIG1heSBjb250YWluIGFu b255bW91cyBwYWdlczogd2hlbiBNQVBfUFJJVkFURQ0KIGFuZCBhIHBhZ2UgaXMgbW9kaWZpZWQs IHRoZSBmaWxlIHBhZ2UgaXMgcmVwbGFjZWQgYnkgYSBwcml2YXRlIGFub255bW91cyBjb3B5Lg0K ICJBbm9uSHVnZVBhZ2VzIiBzaG93cyB0aGUgYW1tb3VudCBvZiBtZW1vcnkgYmFja2VkIGJ5IHRy YW5zcGFyZW50IGh1Z2VwYWdlLg0KLSJIdWdldGxiUGFnZXMiIHNob3dzIHRoZSBhbW1vdW50IG9m IG1lbW9yeSBiYWNrZWQgYnkgaHVnZXRsYmZzIHBhZ2UuDQorIkh1Z2V0bGJQYWdlcyIgc2hvd3Mg dGhlIGFtbW91bnQgb2YgbWVtb3J5IGJhY2tlZCBieSBodWdldGxiZnMgcGFnZSAod2hpY2ggaXMN Citub3QgY291bnRlZCBpbiAiUnNzIiBvciAiUHNzIiBmaWVsZCBmb3IgaGlzdG9yaWNhbCByZWFz b25zLikNCiAiU3dhcCIgc2hvd3MgaG93IG11Y2ggd291bGQtYmUtYW5vbnltb3VzIG1lbW9yeSBp cyBhbHNvIHVzZWQsIGJ1dCBvdXQgb24gc3dhcC4NCiANCiAiVm1GbGFncyIgZmllbGQgZGVzZXJ2 ZXMgYSBzZXBhcmF0ZSBkZXNjcmlwdGlvbi4gVGhpcyBtZW1iZXIgcmVwcmVzZW50cyB0aGUga2Vy bmVsDQotLSANCjIuNC4zDQo=

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

#58 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Michal Hocko

T24gVGh1LCBBdWcgMjAsIDIwMTUgYXQgMDE6MDA6MDVQTSArMDIwMCwgTWljaGFsIEhvY2tvIHdy b3RlOg0KPiBPbiBUaHUgMjAtMDgtMTUgMDg6MjY6MjcsIE5hb3lhIEhvcmlndWNoaSB3cm90ZToN Cj4gPiBDdXJyZW50bHkgdGhlcmUncyBubyBlYXN5IHdheSB0byBnZXQgcGVyLXByb2Nlc3MgdXNh Z2Ugb2YgaHVnZXRsYiBwYWdlcywNCj4gDQo+IElzIHRoaXMgcmVhbGx5IHRoZSBjYXNlIGFmdGVy IHlvdXIgcHJldmlvdXMgcGF0Y2g/IFlvdSBoYXZlIGJvdGggDQo+IEh1Z2V0bGJQYWdlcyBhbmQg S2VybmVsUGFnZVNpemUgd2hpY2ggc2hvdWxkIGJlIHN1ZmZpY2llbnQgbm8/DQoNCldlIGNhbiBj YWxjdXJhdGUgaXQgZnJvbSB0aGVzZSBpbmZvLCBzbyBzYXlpbmcgIm5vIGVhc3kgd2F5IiB3YXMg aW5jb3JyZWN0IDooDQoNCj4gUmVhZGluZyBhIHNpbmdsZSBmaWxlIGlzLCBvZiBjb3Vyc2UsIGVh c2llciBidXQgaXMgaXQgcmVhbGx5IHdvcnRoIHRoZQ0KPiBhZGRpdGlvbmFsIGNvZGU/IEkgaGF2 ZW4ndCByZWFsbHkgbG9va2VkIGF0IHRoZSBwYXRjaCBzbyBJIG1pZ2h0IGJlDQo+IG1pc3Npbmcg c29tZXRoaW5nIGJ1dCB3aGF0IHdvdWxkIGJlIGFuIGFkdmFudGFnZSBvdmVyIHJlYWRpbmcNCj4g L3Byb2MvPHBpZD4vc21hcHMgYW5kIGV4dHJhY3RpbmcgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhl cmU/DQoNCk15IGZpcnN0IGlkZWEgd2FzIGp1c3QgInVzZXJzIHNob3VsZCBmZWVsIGl0IHVzZWZ1 bCIsIGJ1dCBwZXJtaXNzaW9uIGFzIERhdmlkDQpjb21tZW50ZWQgc291bmRzIGEgZ29vZCB0ZWNo bmljYWwgcmVhc29uIHRvIG1lLg0KDQpUaGFua3MsDQpOYW95YSBIb3JpZ3VjaGk=

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

#56 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to David Rientjes
Quoted 8 lines · David Rientjes
Quoted 6 lines · Michal Hocko
Quoted 1 line · Naoya Horiguchi

Currently there's no easy way to get per-process usage of hugetlb pages,

Is this really the case after your previous patch? You have both HugetlbPages and KernelPageSize which should be sufficient no?

Quoted 7 lines
Quoted 5 lines

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

/proc/pid/smaps requires root, /proc/pid/status doesn't.

Both mmotm and linus tree have
REG("smaps", S_IRUGO, proc_pid_smaps_operations),

and opening the file requires PTRACE_MODE_READ. So I do not see any requirement for root here. Or did you mean that you need root to examine all processes? That would be true but I am wondering why would be a regular user interested in this break out numbers. Hugetlb management sounds pretty much like an administrative or very specialized thing.

Quoted 1 line

From my understanding of the discussion there is no usecase to have this

information world readable. Is this correct?

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#44 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Naoya Horiguchi

On Thu 20-08-15 23:20:12, Naoya Horiguchi wrote:
[...]

Quoted 14 lines

From: Naoya Horiguchi <[email protected]>
Date: Fri, 21 Aug 2015 08:13:31 +0900
Subject: [PATCH] Documentation/filesystems/proc.txt: give additional comment
about hugetlb usage

---
 Documentation/filesystems/proc.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
Documentation/filesystems/proc.txt +0 -0
index f561fc46e41b..b775b6faaeda 100644

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 453

Quoted 9 lines
Documentation/filesystems/proc.txt +2 -1
@@ -446,7 +446,8 @@ indicates the amount of memory currently marked as referenced or accessed.
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
 "AnonHugePages" shows the ammount of memory backed by transparent hugepage.
-"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page (which is
+not counted in "Rss" or "Pss" field for historical reasons.)
 "Swap" shows how much would-be-anonymous memory is also used, but out on swap.
 
 "VmFlags" field deserves a separate description. This member represents the kernel

Thank you!

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#59 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Naoya Horiguchi

On Thu 20-08-15 23:34:51, Naoya Horiguchi wrote:
[...]

Quoted 7 lines
Quoted 4 lines

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

My first idea was just "users should feel it useful", but permission as David commented sounds a good technical reason to me.

9 files changed, 112 insertions(+), 1 deletion(-)

is quite a lot especially when it touches hot paths like fork so it better should have a good usecase. I have already asked in the other email but is actually anybody requesting this? Nice to have is not a good justification IMO.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#60 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 10 lines · Michal Hocko

On Thu 20-08-15 23:34:51, Naoya Horiguchi wrote:
[...]

Quoted 7 lines
Quoted 4 lines

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

My first idea was just "users should feel it useful", but permission as David commented sounds a good technical reason to me.

Quoted 6 lines
9 files changed, 112 insertions(+), 1 deletion(-)

is quite a lot especially when it touches hot paths like fork so it better should have a good usecase. I have already asked in the other email but is actually anybody requesting this? Nice to have is not a good justification IMO.

I need some way to judge the real rss of a process, including huge pages. No strong opinion on implementation details, but something is clearly needed.

If you have processes with 99% huge pages, you are currently reduced to guesswork.

Jorn

--
Journalism is printing what someone else does not want printed; everything else is public relations.
-- George Orwell

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

#57 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Michal Hocko
Quoted 4 lines · Michal Hocko

Both mmotm and linus tree have
REG("smaps", S_IRUGO, proc_pid_smaps_operations),

Quoted 8 lines

and opening the file requires PTRACE_MODE_READ. So I do not see any requirement for root here. Or did you mean that you need root to examine all processes? That would be true but I am wondering why would be a regular user interested in this break out numbers. Hugetlb management sounds pretty much like an administrative or very specialized thing.

From my understanding of the discussion there is no usecase to have this information world readable. Is this correct?

Well, tools like top currently display rss. Once we have some interface, I would like a version of top that displays the true rss including hugepages (hrss maybe?).

If we make such a tool impossible today, someone will complain about it in the future and we created a new mess for ourselves. I think it is trouble enough to deal with the old one.

Jorn

--
Denying any reality for any laudable political goal is a bad strategy. When the facts come out, the discovery of the facts will undermine the laudable political goals.
-- Jared Diamond

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

#61 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Jörn Engel
Quoted 13 lines · Jorn Engel
Quoted 12 lines · Michal Hocko

On Thu 20-08-15 23:34:51, Naoya Horiguchi wrote:
[...]

Quoted 7 lines
Quoted 4 lines

Reading a single file is, of course, easier but is it really worth the additional code? I haven't really looked at the patch so I might be missing something but what would be an advantage over reading /proc/<pid>/smaps and extracting the information from there?

My first idea was just "users should feel it useful", but permission as David commented sounds a good technical reason to me.

9 files changed, 112 insertions(+), 1 deletion(-)
Quoted 8 lines
Quoted 4 lines

is quite a lot especially when it touches hot paths like fork so it better should have a good usecase. I have already asked in the other email but is actually anybody requesting this? Nice to have is not a good justification IMO.

I need some way to judge the real rss of a process, including huge pages. No strong opinion on implementation details, but something is clearly needed.

The current implementation makes me worry. Is the per hstate break down really needed? The implementation would be much more easier without it.

Quoted 2 lines

If you have processes with 99% huge pages, you are currently reduced to guesswork.

If you have 99% of hugetlb pages then your load is rather specific and I would argue that /proc/<pid>/smaps (after patch 1) is a much better way to get what you want.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#62 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 3 lines · Michal Hocko

The current implementation makes me worry. Is the per hstate break down really needed? The implementation would be much more easier without it.

Yes, it's needed. It provides a complete picture of what statically reserved hugepages are in use and we're not going to change the implementation when it is needed to differentiate between variable hugetlb page sizes that risk breaking existing userspace parsers.

Quoted 4 lines

If you have 99% of hugetlb pages then your load is rather specific and I would argue that /proc/<pid>/smaps (after patch 1) is a much better way to get what you want.

Some distributions change the permissions of smaps, as already stated, for pretty clear security reasons since it can be used to defeat existing protection. There's no reason why hugetlb page usage should not be exported in the same manner and location as memory usage.

Sheesh.

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

#63 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 10 lines · David Rientjes
Quoted 3 lines · Michal Hocko

The current implementation makes me worry. Is the per hstate break down really needed? The implementation would be much more easier without it.

Yes, it's needed. It provides a complete picture of what statically reserved hugepages are in use and we're not going to change the implementation when it is needed to differentiate between variable hugetlb page sizes that risk breaking existing userspace parsers.

I thought the purpose was to give the amount of hugetlb based resident memory. At least this is what Jorn was asking for AFAIU. /proc/<pid>/status should be as lightweight as possible. The current implementation is quite heavy as already pointed out. So I am really curious whether this is _really_ needed. I haven't heard about a real usecase except for top displaying HRss which doesn't need the break down values. You have brought that up already
http://marc.info/?l=linux-mm&m=143941143109335&w=2 and nobody actually asked for it. "I do not mind having it" is not an argument for inclusion especially when the implementation is more costly and touches hot paths.

Quoted 8 lines
Quoted 3 lines

If you have 99% of hugetlb pages then your load is rather specific and I would argue that /proc/<pid>/smaps (after patch 1) is a much better way to get what you want.

Some distributions change the permissions of smaps, as already stated, for pretty clear security reasons since it can be used to defeat existing protection. There's no reason why hugetlb page usage should not be exported in the same manner and location as memory usage.

/proc/<pid>/status provides only per-memory-type break down information (locked, data, stack, etc...). Different hugetlb sizes are still a hugetlb memory. So I am not sure I understand you argument here.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#64 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 2 lines · Michal Hocko

I thought the purpose was to give the amount of hugetlb based resident memory.

Persistent hugetlb memory is always resident, the goal is to show what is currently mapped.

Quoted 10 lines

At least this is what JA?rn was asking for AFAIU. /proc/<pid>/status should be as lightweight as possible. The current implementation is quite heavy as already pointed out. So I am really curious whether this is _really_ needed. I haven't heard about a real usecase except for top displaying HRss which doesn't need the break down values. You have brought that up already
http://marc.info/?l=linux-mm&m=143941143109335&w=2 and nobody actually asked for it. "I do not mind having it" is not an argument for inclusion especially when the implementation is more costly and touches hot paths.

It iterates over HUGE_MAX_HSTATE and reads atomic usage counters twice. On x86, HUGE_MAX_HSTATE == 2. I don't consider that to be expensive.

If you are concerned about the memory allocation of struct hugetlb_usage, it could easily be embedded directly in struct mm_struct.

#65 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 19 lines · David Rientjes
Quoted 2 lines · Michal Hocko

I thought the purpose was to give the amount of hugetlb based resident memory.

Persistent hugetlb memory is always resident, the goal is to show what is currently mapped.

Quoted 10 lines

At least this is what Jorn was asking for AFAIU. /proc/<pid>/status should be as lightweight as possible. The current implementation is quite heavy as already pointed out. So I am really curious whether this is _really_ needed. I haven't heard about a real usecase except for top displaying HRss which doesn't need the break down values. You have brought that up already
http://marc.info/?l=linux-mm&m=143941143109335&w=2 and nobody actually asked for it. "I do not mind having it" is not an argument for inclusion especially when the implementation is more costly and touches hot paths.

Quoted 1 line

It iterates over HUGE_MAX_HSTATE and reads atomic usage counters twice.

I am not worried about /proc/<pid>/status read path. That one is indeed trivial.

Quoted 4 lines

On x86, HUGE_MAX_HSTATE == 2. I don't consider that to be expensive.

If you are concerned about the memory allocation of struct hugetlb_usage, it could easily be embedded directly in struct mm_struct.

Yes I am concerned about that and

9 files changed, 112 insertions(+), 1 deletion(-)

for something that is even not clear to be really required. And I still haven't heard any strong usecase to justify it.

Can we go with the single and much simpler cumulative number first and only add the break down list if it is _really_ required? We can even document that the future version of /proc/<pid>/status might add an additional information to prepare all the parsers to be more careful.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#66 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 7 lines · Michal Hocko
Quoted 5 lines

On x86, HUGE_MAX_HSTATE == 2. I don't consider that to be expensive.

If you are concerned about the memory allocation of struct hugetlb_usage, it could easily be embedded directly in struct mm_struct.

Yes I am concerned about that and

Quoted 8 lines
9 files changed, 112 insertions(+), 1 deletion(-)

for something that is even not clear to be really required. And I still haven't heard any strong usecase to justify it.

Can we go with the single and much simpler cumulative number first and only add the break down list if it is _really_ required? We can even document that the future version of /proc/<pid>/status might add an additional information to prepare all the parsers to be more careful.

I don't care much which way we decide. But I find your reasoning a bit worrying. If someone asks for a by-size breakup of hugepages in a few years, you might have existing binaries that depend on the _absence_ of those extra characters on the line.

Compare:
HugetlbPages: 18432 kB
HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

Once someone has written a script that greps for 'HugetlbPages:.*kB$', you have lost the option of adding anything else to the line. You have created yet another ABI compatibility headache today in order to save 112 lines of code.

That may be a worthwhile tradeoff, I don't know. But at least I realize there is a cost, while you seem to ignore that component. There is value in not painting yourself into a corner.

Jorn

--
A quarrel is quickly settled when deserted by one party; there is no battle unless there be two.
-- Seneca

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

#67 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

Quoted 11 lines · JA?rn Engel
Quoted 4 lines · Michal Hocko

Can we go with the single and much simpler cumulative number first and only add the break down list if it is _really_ required? We can even document that the future version of /proc/<pid>/status might add an additional information to prepare all the parsers to be more careful.

I don't care much which way we decide. But I find your reasoning a bit worrying. If someone asks for a by-size breakup of hugepages in a few years, you might have existing binaries that depend on the _absence_ of those extra characters on the line.

Quoted 9 lines

Compare:
HugetlbPages: 18432 kB
HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

Once someone has written a script that greps for 'HugetlbPages:.*kB$', you have lost the option of adding anything else to the line. You have created yet another ABI compatibility headache today in order to save 112 lines of code.

This is exactly the concern that I have brought up in this thread. We have no other way to sanely export the breakdown in hugepage size without new fields being added later with the hstate size being embedded in the name itself.

I agree with the code as it stands in -mm today and I'm thankful to Naoya that a long-term maintainable API has been established. Respectfully, I have no idea why we are still talking about this and I'm not going to be responding further unless something changes in -mm.

#68 lore raw

Re: [PATCH v5 2/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/status

In reply to Jörn Engel
Quoted 22 lines · Jorn Engel
Quoted 7 lines · Michal Hocko
Quoted 5 lines

On x86, HUGE_MAX_HSTATE == 2. I don't consider that to be expensive.

If you are concerned about the memory allocation of struct hugetlb_usage, it could easily be embedded directly in struct mm_struct.

Yes I am concerned about that and

Quoted 8 lines
9 files changed, 112 insertions(+), 1 deletion(-)

for something that is even not clear to be really required. And I still haven't heard any strong usecase to justify it.

Can we go with the single and much simpler cumulative number first and only add the break down list if it is _really_ required? We can even document that the future version of /proc/<pid>/status might add an additional information to prepare all the parsers to be more careful.

I don't care much which way we decide. But I find your reasoning a bit worrying. If someone asks for a by-size breakup of hugepages in a few years, you might have existing binaries that depend on the _absence_ of those extra characters on the line.

Quoted 6 lines

Compare:
HugetlbPages: 18432 kB
HugetlbPages: 1069056 kB (1*1048576kB 10*2048kB)

Once someone has written a script that greps for 'HugetlbPages:.*kB$', you have lost the option of adding anything else to the line.

If you think that an explicit note in the documentation is not sufficient then I believe we can still handle it backward compatible. Like separate entries for each existing hugetlb page:
HugetlbPages: 1069056 kB
Hugetlb2MPages: 20480 kB
Hugetlb1GPages: 1048576 kB

or something similar. I would even argue this would be slightly easier to parse. So it is not like we would be locked into anything.

Quoted 7 lines

You have
created yet another ABI compatibility headache today in order to save 112 lines of code.

That may be a worthwhile tradeoff, I don't know. But at least I realize there is a cost, while you seem to ignore that component. There is value in not painting yourself into a corner.

My primary point was that we are adding a code for a feature nobody actually asked for just because somebody might ask for it in future.

Signature · 8 lines
Michal Hocko
SUSE Labs

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#45 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Naoya Horiguchi
Quoted 51 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +2 -0
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 447

Quoted 8 lines
Documentation/filesystems/proc.txt +3 -2
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.

There is no distinction between "private" and "shared" in this "huge page" accounting right? Would it be possible to account for the huge pages in the {Private,Shared}_{Clean,Dirty} fields? Or otherwise split the huge page accounting into shared/private?

thanks!
PA!draig.

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

#46 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 54 lines · Pádraig Brady
Quoted 53 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +2 -0
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
Quoted 8 lines

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 447

Quoted 6 lines
Documentation/filesystems/proc.txt +3 -2
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.

There is no distinction between "private" and "shared" in this "huge page" accounting right?

Right for current version. And I think that private/shared distinction gives some help.

Quoted 2 lines

Would it be possible to account for the huge pages in the {Private,Shared}_{Clean,Dirty} fields? Or otherwise split the huge page accounting into shared/private?

As for clean/dirty distinction, I'm not sure how it's worthwhile because hugetlb pages are always on memory and never swapped out (userspace doesn't care about dirtiness of hugetlb?).

According to commit log of commit b4d1d99fdd8b ("hugetlb: handle updating of ACCESSED and DIRTY in hugetlb_fault()"), dirty bit of hugetlb is maintained to make arch-specific TLB handling convenient. It looks purely kernel-internal, so I think we don't have to expose it.

Thanks,
Naoya Horiguchi���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#47 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 64 lines · Horiguchi Naoya(堀口 直也)
Quoted 54 lines · Pádraig Brady
Quoted 53 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +2 -0
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
Quoted 8 lines

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 447

Quoted 6 lines
Documentation/filesystems/proc.txt +3 -2
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.

There is no distinction between "private" and "shared" in this "huge page" accounting right?

Quoted 5 lines

Right for current version. And I think that private/shared distinction gives some help.

Quoted 2 lines

Would it be possible to account for the huge pages in the {Private,Shared}_{Clean,Dirty} fields? Or otherwise split the huge page accounting into shared/private?

Sorry, I didn't catch you properly.
I think that accounting for hugetlb pages should be done only with HugetlbPages or any other new field for hugetlb, in order not to break the behavior of existing fields. So splitting HugetlbPages into shared/private looks good to me.

Thanks,
Naoya Horiguchi

Quoted 11 lines

As for clean/dirty distinction, I'm not sure how it's worthwhile because hugetlb pages are always on memory and never swapped out (userspace doesn't care about dirtiness of hugetlb?).

According to commit log of commit b4d1d99fdd8b ("hugetlb: handle updating of ACCESSED and DIRTY in hugetlb_fault()"), dirty bit of hugetlb is maintained to make arch-specific TLB handling convenient. It looks purely kernel-internal, so I think we don't have to expose it.

Thanks,
Naoya Horiguchi���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�

#48 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 68 lines · Naoya Horiguchi
Quoted 67 lines · On Mon, Sep 07, 2015 at 02:23:44AM +0000, Horiguchi Naoya(a ?a?GBP c?'a1?)…
Quoted 54 lines · PA!draig Brady
Quoted 53 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +2 -0
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
Quoted 8 lines

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 447

Quoted 6 lines
Documentation/filesystems/proc.txt +3 -2
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.

There is no distinction between "private" and "shared" in this "huge page" accounting right?

Right for current version. And I think that private/shared distinction gives some help.

Quoted 7 lines
Quoted 2 lines
Quoted 2 lines

Would it be possible to account for the huge pages in the {Private,Shared}_{Clean,Dirty} fields? Or otherwise split the huge page accounting into shared/private?

Sorry, I didn't catch you properly.
I think that accounting for hugetlb pages should be done only with HugetlbPages or any other new field for hugetlb, in order not to break the behavior of existing fields.

On a more general note I'd be inclined to just account for hugetlb pages in Rss and {Private,Shared}_Dirty and fix any tools that double count.

Quoted 1 line

So splitting HugetlbPages into shared/private looks good to me.

Yes this is the most compatible solution,
and will allow one to accurately determine
how much core mem a process is using.

thanks!
PA!draig.

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

#49 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 72 lines · PA!draig Brady
Quoted 71 lines · Naoya Horiguchi
Quoted 69 lines · On Mon, Sep 07, 2015 at 02:23:44AM +0000, Horiguchi Naoya(a ?a?GBP c?'a1?)…
Quoted 54 lines · PA!draig Brady
Quoted 53 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

  Rss:                   0 kB
  Pss:                   0 kB
  Shared_Clean:          0 kB
  Shared_Dirty:          0 kB
  Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:            0 kB
  Anonymous:             0 kB
  AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
 Documentation/filesystems/proc.txt |  7 +++++--
 fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +2 -0
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
 Private_Dirty:         0 kB
 Referenced:          892 kB
 Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
 Swap:                  0 kB
 KernelPageSize:        4 kB
 MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
 "Anonymous" shows the amount of memory that does not belong to any file.  Even
 a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
Quoted 8 lines

Documentation/filesystems/proc.txt indicates the amount of memory currently marked as referenced or accessed. · line 447

Quoted 6 lines
Documentation/filesystems/proc.txt +3 -2
 and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.

There is no distinction between "private" and "shared" in this "huge page" accounting right?

Right for current version. And I think that private/shared distinction gives some help.

Quoted 2 lines

Would it be possible to account for the huge pages in the {Private,Shared}_{Clean,Dirty} fields? Or otherwise split the huge page accounting into shared/private?

Quoted 8 lines
Quoted 4 lines

Sorry, I didn't catch you properly.
I think that accounting for hugetlb pages should be done only with HugetlbPages or any other new field for hugetlb, in order not to break the behavior of existing fields.

On a more general note I'd be inclined to just account for hugetlb pages in Rss and {Private,Shared}_Dirty and fix any tools that double count.

By the same argument I presume the existing THP "AnonHugePages" smaps field is not accounted for in the {Private,Shared}_... fields?
I.E. AnonHugePages may also benefit from splitting to Private/Shared?

thanks,
PA!draig.

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

#51 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Naoya Horiguchi
Quoted 21 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

   Rss:                   0 kB
   Pss:                   0 kB
   Shared_Clean:          0 kB
   Shared_Dirty:          0 kB
   Private_Clean:         0 kB
   Private_Dirty:         0 kB
   Referenced:            0 kB
   Anonymous:             0 kB
   AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Quoted 3 lines

Sorry for coming late to this thread. It's a nice improvement, but I find it somewhat illogical that the per-process stats (status) are more detailed than the per-mapping stats (smaps) with respect to the size breakdown. I would expect it to be the other way around. That would simplify the per-process accounting (I realize this has been a hot topic already), and allow those who really care to look at smaps.

I'm just not sure about the format in that case. In smaps, a line per size would probably make more sense. Even in status, the extra information in parentheses looks somewhat out of place. But of course, adding shared/private breakdown as suggested would lead to an explosion of number of lines in that case...

Quoted 99 lines

---
v3 -> v4:
- suspend Acked-by tag because v3->v4 change is not trivial
- I stated in previous discussion that HugetlbPages line can contain page size info, but that's not necessary because we already have KernelPageSize info.
- merged documentation update, where the current documentation doesn't mention AnonHugePages, so it's also added.

---
  Documentation/filesystems/proc.txt |  7 +++++--
  fs/proc/task_mmu.c                 | 29 +++++++++++++++++++++++++++++
  2 files changed, 34 insertions(+), 2 deletions(-)
Documentation/filesystems/proc.txt +5 -2
index 6f7fafde0884..22e40211ef64 100644
@@ -423,6 +423,8 @@ Private_Clean:         0 kB
  Private_Dirty:         0 kB
  Referenced:          892 kB
  Anonymous:             0 kB
+AnonHugePages:         0 kB
+HugetlbPages:          0 kB
  Swap:                  0 kB
  KernelPageSize:        4 kB
  MMUPageSize:           4 kB
@@ -440,8 +442,9 @@ indicates the amount of memory currently marked as referenced or accessed.
  "Anonymous" shows the amount of memory that does not belong to any file.  Even
  a mapping associated with a file may contain anonymous pages: when MAP_PRIVATE
  and a page is modified, the file page is replaced by a private anonymous copy.
-"Swap" shows how much would-be-anonymous memory is also used, but out on
-swap.
+"AnonHugePages" shows the ammount of memory backed by transparent hugepage.
+"HugetlbPages" shows the ammount of memory backed by hugetlbfs page.
+"Swap" shows how much would-be-anonymous memory is also used, but out on swap.
 
  "VmFlags" field deserves a separate description. This member represents the kernel
  flags associated with the particular virtual memory area in two letter encoded
fs/proc/task_mmu.c +28 -0
index ca1e091881d4..2c37938b82ee 100644
@@ -445,6 +445,7 @@ struct mem_size_stats {
  	unsigned long anonymous;
  	unsigned long anonymous_thp;
  	unsigned long swap;
+	unsigned long hugetlb;
  	u64 pss;
  };
 
@@ -610,12 +611,38 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma)
  	seq_putc(m, '\n');
  }
 
+#ifdef CONFIG_HUGETLB_PAGE
+static int smaps_hugetlb_range(pte_t *pte, unsigned long hmask,
+				 unsigned long addr, unsigned long end,
+				 struct mm_walk *walk)
+{
+	struct mem_size_stats *mss = walk->private;
+	struct vm_area_struct *vma = walk->vma;
+	struct page *page = NULL;
+
+	if (pte_present(*pte)) {
+		page = vm_normal_page(vma, addr, *pte);
+	} else if (is_swap_pte(*pte)) {
+		swp_entry_t swpent = pte_to_swp_entry(*pte);
+
+		if (is_migration_entry(swpent))
+			page = migration_entry_to_page(swpent);
+	}
+	if (page)
+		mss->hugetlb += huge_page_size(hstate_vma(vma));
+	return 0;
+}
+#endif /* HUGETLB_PAGE */
+
  static int show_smap(struct seq_file *m, void *v, int is_pid)
  {
  	struct vm_area_struct *vma = v;
  	struct mem_size_stats mss;
  	struct mm_walk smaps_walk = {
  		.pmd_entry = smaps_pte_range,
+#ifdef CONFIG_HUGETLB_PAGE
+		.hugetlb_entry = smaps_hugetlb_range,
+#endif
  		.mm = vma->vm_mm,
  		.private = &mss,
  	};
@@ -637,6 +664,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
  		   "Referenced:     %8lu kB\n"
  		   "Anonymous:      %8lu kB\n"
  		   "AnonHugePages:  %8lu kB\n"
+		   "HugetlbPages:   %8lu kB\n"
  		   "Swap:           %8lu kB\n"
  		   "KernelPageSize: %8lu kB\n"
  		   "MMUPageSize:    %8lu kB\n"

fs/proc/task_mmu.c static int show_smap(struct seq_file *m, void *v, int is_pid) · line 685

Quoted 7 lines
fs/proc/task_mmu.c +1 -0
@@ -651,6 +679,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid)
  		   mss.referenced >> 10,
  		   mss.anonymous >> 10,
  		   mss.anonymous_thp >> 10,
+		   mss.hugetlb >> 10,
  		   mss.swap >> 10,
  		   vma_kernel_pagesize(vma) >> 10,
  		   vma_mmu_pagesize(vma) >> 10,

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

#52 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

Quoted 26 lines · Vlastimil Babka
Quoted 21 lines · Naoya Horiguchi

Currently /proc/PID/smaps provides no usage info for vma(VM_HUGETLB), which is inconvenient when we want to know per-task or per-vma base hugetlb usage. To solve this, this patch adds a new line for hugetlb usage like below:

Size: 20480 kB

   Rss:                   0 kB
   Pss:                   0 kB
   Shared_Clean:          0 kB
   Shared_Dirty:          0 kB
   Private_Clean:         0 kB
   Private_Dirty:         0 kB
   Referenced:            0 kB
   Anonymous:             0 kB
   AnonHugePages:         0 kB

HugetlbPages: 18432 kB
Swap: 0 kB
KernelPageSize: 2048 kB
MMUPageSize: 2048 kB
Locked: 0 kB
VmFlags: rd wr mr mw me de ht

Quoted 3 lines
Quoted 7 lines

Sorry for coming late to this thread. It's a nice improvement, but I find it somewhat illogical that the per-process stats (status) are more detailed than the per-mapping stats (smaps) with respect to the size breakdown. I would expect it to be the other way around. That would simplify the per-process accounting (I realize this has been a hot topic already), and allow those who really care to look at smaps.

Smaps shows the pagesize for the hugepage of the vma and the rss, I believe you have all the information needed. Some distributions also change smaps to only be readable by the owner or root for security reasons.

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

#69 lore raw

PATCH 1/1 mm: migrate: hugetlb: putback destination hugepage to active list

In reply to Naoya Horiguchi

Since commit bcc54222309c ("mm: hugetlb: introduce page_huge_active") each hugetlb page maintains its active flag to avoid a race condition between multiple calls of isolate_huge_page(), but current kernel doesn't set the flag on a hugepage allocated by migration because the proper putback routine isn't called. This means that users could still encounter the race referred to by bcc54222309c in this special case, so this patch fixes it.

Fixes bcc54222309c ("mm: hugetlb: introduce page_huge_active")
---
 mm/migrate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
index c3cb566af3e2..7452a00bbb50 100644
@@ -1075,7 +1075,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
 	if (rc != MIGRATEPAGE_SUCCESS && put_new_page)
 		put_new_page(new_hpage, private);
 	else
-		put_page(new_hpage);
+		putback_active_hugepage(new_hpage);
 
 	if (result) {
 		if (rc)
Signature · 1 line
2.4.3
#70 lore raw

Re: [PATCH v1] mm: migrate: hugetlb: putback destination hugepage to active list

my bad, this patch is totally unrelated to the thread the previous email replied to. I just mishandled my script wrapping git-send-email, sorry.

But just resending patch seems to be noisy, so I want this to be reviewed on this email.
If it's inconvenient or uncommon way of submission, please let me know and I'll resend in a new thread.

Thanks,
Naoya Horiguchi

Quoted 35 lines · Naoya Horiguchi

Since commit bcc54222309c ("mm: hugetlb: introduce page_huge_active") each hugetlb page maintains its active flag to avoid a race condition between multiple calls of isolate_huge_page(), but current kernel doesn't set the flag on a hugepage allocated by migration because the proper putback routine isn't called. This means that users could still encounter the race referred to by bcc54222309c in this special case, so this patch fixes it.

Fixes bcc54222309c ("mm: hugetlb: introduce page_huge_active")
---
 mm/migrate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
mm/migrate.c +1 -1
index c3cb566af3e2..7452a00bbb50 100644
@@ -1075,7 +1075,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
 	if (rc != MIGRATEPAGE_SUCCESS && put_new_page)
 		put_new_page(new_hpage, private);
 	else
-		put_page(new_hpage);
+		putback_active_hugepage(new_hpage);
 
 	if (result) {
 		if (rc)
Signature · 7 lines
2.4.3

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#50 lore raw

Re: [PATCH v5 1/2] mm: hugetlb: proc: add HugetlbPages field to /proc/PID/smaps

In reply to Pádraig Brady

On Mon, Sep 07, 2015 at 11:52:41AM +0100, Pádraig Brady wrote:
...

Quoted 4 lines

By the same argument I presume the existing THP "AnonHugePages" smaps field is not accounted for in the {Private,Shared}_... fields?
I.E. AnonHugePages may also benefit from splitting to Private/Shared?

smaps_pmd_entry() not only increments mss->anonymous_thp, but also calls smaps_account() which updates mss->anonymous, mss->referenced and mss->{shared,private}_{clean,dirty}, so thp's shared/private characteristic is included in other existing fields.
I think that even if we know the thp-specific shared/private profiles, it might be hard to do something beneficial using that information, so I feel keeping this field as-is is ok for now.

Thanks,
Naoya Horiguchi���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m���� ������?�I�