mm/rmap.c: split huge pmd when it really is
Subsystems (2)
PATCH v2 1/1 mm/rmap.c: split huge pmd when it really is
When page is not NULL, function is called by try_to_unmap_one() with TTU_SPLIT_HUGE_PMD set. There are two cases to call try_to_unmap_one() with TTU_SPLIT_HUGE_PMD set:
* unmap_page()
* shrink_page_list()
In both case, the page passed to try_to_unmap_one() is PageHead() of the THP. If this page's mapping address in process is not HPAGE_PMD_SIZE aligned, this means the THP is not mapped as PMD THP in this process. This could happen when we do mremap() a PMD size range to an un-aligned address.
Currently, this case is handled by following check in __split_huge_pmd() luckily.
page != pmd_page(*pmd)
This patch checks the address to skip some work.
---
v2: move the check into split_huge_pmd_address().
--- mm/huge_memory.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
mm/huge_memory.c +16 -0
@@ -2342,6 +2342,22 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,pud_t *pud;pmd_t *pmd; +/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* +* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ; + pgd =pgd_offset (vma->vm_mm, address);if (!pgd_present (*pgd))return ;
Signature · 1 line
2.17.1
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.
Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
The description here is confusing to me.
Quoted 5 lines
mm/huge_memory.c +5
-0+/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +*
mm/huge_memory.c void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, · line 2359
Quoted 10 lines
mm/huge_memory.c +10
-0+* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ;
Repeating 75% of it as comments doesn't make it any less confusing. And it feels like we're digging a pothole for someone to fall into later. Why not make it make sense ...
if (page && !IS_ALIGNED(address, page_size(page)) return;
Quoted 14 lines · Matthew Wilcox
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.
Quoted 9 lines
Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
The description here is confusing to me.
Sorry for the confusion.
Below is my understanding, if not correct or proper, just let me know :-)
According to current comment in __split_huge_pmd(), we check pmd_page with page for migration case. While actually, this check also helps in the following two cases when page already split-ed:
* page just split-ed in place
* page split-ed and moved to non-PMD aligned address
In both cases, pmd_page() is pointing to the PTE level page table. That's why we don't split one already split-ed THP page.
If current code really intend to cover these two cases, sorry for my poor understanding.
Quoted 20 lines
Quoted 5 lines
mm/huge_memory.c +5
-0+/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* mm/huge_memory.c void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, · line 2359
Quoted 10 lines
mm/huge_memory.c +10
-0+* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ;Repeating 75% of it as comments doesn't make it any less confusing. And it feels like we're digging a pothole for someone to fall into later. Why not make it make sense ...
Quoted 2 lines
if (page && !IS_ALIGNED(address, page_size(page)) return;
Hmm... Use HPAGE_PMD_SIZE here wants to emphasize we want the address to be PMD aligned. If just use page_size() here, may confuse the audience?
Signature · 2 lines
Wei Yang Help you, Help me
Quoted 62 lines · Wei Yang
Quoted 14 lines · Matthew Wilcox
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 9 lines
Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
The description here is confusing to me.
Sorry for the confusion.
Below is my understanding, if not correct or proper, just let me know :-)
According to current comment in
__split_huge_pmd(), we checkpmd_pagewith page for migration case. While actually, this check also helps in the following two cases when page already split-ed:* page just split-ed in place
* page split-ed and moved to non-PMD aligned addressIn both cases,
pmd_page()is pointing to the PTE level page table. That's why we don't split one already split-ed THP page.If current code really intend to cover these two cases, sorry for my poor understanding.
Quoted 20 lines
Quoted 5 lines
mm/huge_memory.c +5
-0+/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* mm/huge_memory.c void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, · line 2359
Quoted 10 lines
mm/huge_memory.c +10
-0+* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ;Repeating 75% of it as comments doesn't make it any less confusing. And it feels like we're digging a pothole for someone to fall into later. Why not make it make sense ...
Quoted 5 lines
Quoted 2 lines
if (page && !IS_ALIGNED(address, page_size(page)) return;Hmm... Use
HPAGE_PMD_SIZEhere wants to emphasize we want the address to be PMD aligned. If just usepage_size()here, may confuse the audience?
I'm OK with using HPAGE_PMD_SIZE here. I was trying to future-proof this function for supporting 64kB pages with a 4kB page size on ARM, but this function will need changes for that anyway, so I'm OK with your suggestion.
Quoted 66 lines · Matthew Wilcox
Quoted 65 lines · Wei Yang
Quoted 14 lines · Matthew Wilcox
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 9 lines
Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
The description here is confusing to me.
Sorry for the confusion.
Below is my understanding, if not correct or proper, just let me know :-)
According to current comment in
__split_huge_pmd(), we checkpmd_pagewith page for migration case. While actually, this check also helps in the following two cases when page already split-ed:* page just split-ed in place
* page split-ed and moved to non-PMD aligned addressIn both cases,
pmd_page()is pointing to the PTE level page table. That's why we don't split one already split-ed THP page.If current code really intend to cover these two cases, sorry for my poor understanding.
Quoted 22 lines
Quoted 5 lines
mm/huge_memory.c +5
-0+/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* mm/huge_memory.c void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address, · line 2359
Quoted 10 lines
mm/huge_memory.c +10
-0+* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ;Repeating 75% of it as comments doesn't make it any less confusing. And it feels like we're digging a pothole for someone to fall into later. Why not make it make sense ...
if (page && !IS_ALIGNED(address, page_size(page)) return;
Quoted 7 lines
Quoted 2 lines
Hmm... Use
HPAGE_PMD_SIZEhere wants to emphasize we want the address to be PMD aligned. If just usepage_size()here, may confuse the audience?I'm OK with using
HPAGE_PMD_SIZEhere. I was trying to future-proof this function for supporting 64kB pages with a 4kB page size on ARM, but this function will need changes for that anyway, so I'm OK with your suggestion.
Thanks for your comments. :-)
Signature · 2 lines
Wei Yang Help you, Help me
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.
Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched
963 195
988 40
895 78Average 948 104
So the change reduced 90% time for function split_huge_pmd_address().
For the 2nd comment, the vma check. Let me take a further look to analysis.
Thanks for Kirill's suggestion.
Quoted 38 lines
Signed-off-by Wei Yang <[email protected]>---
v2: move the check intosplit_huge_pmd_address().
---mm/huge_memory.c| 16 ++++++++++++++++1 file changed, 16 insertions(+)mm/huge_memory.c +16
-0@@ -2342,6 +2342,22 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,pud_t *pud;pmd_t *pmd; +/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* +* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ; + pgd =pgd_offset (vma->vm_mm, address);if (!pgd_present (*pgd))return ;Signature · 1 line
2.17.1
Signature · 2 lines
Wei Yang Help you, Help me
Quoted 34 lines · Wei Yang
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched 963 195 988 40 895 78
Quoted 8 lines
Average 948 104
So the change reduced 90% time for function
split_huge_pmd_address().For the 2nd comment, the vma check. Let me take a further look to analysis.
Thanks for Kirill's suggestion.
For 2nd comment, check vma could hold huge page.
You mean do this check ?
vma->vm_start <= address && vma->vm_end >= address + HPAGE_PMD_SIZE
This happens after munmap a partial of the THP range? After doing so, we can skip split_pmd for this case.
Quoted 42 lines
Quoted 38 lines
Signed-off-by Wei Yang <[email protected]>---
v2: move the check intosplit_huge_pmd_address().
---mm/huge_memory.c| 16 ++++++++++++++++1 file changed, 16 insertions(+)mm/huge_memory.c +16
-0@@ -2342,6 +2342,22 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,pud_t *pud;pmd_t *pmd; +/* +* When page is not NULL, function is called by try_to_unmap_one() +* with TTU_SPLIT_HUGE_PMD set. There are two places set +* TTU_SPLIT_HUGE_PMD +* +* unmap_page() +* shrink_page_list() +* +* In both cases, the "page" here is the PageHead() of a THP. +* +* If the page is not a PMD mapped huge page, e.g. after mremap(), it +* is not necessary to split it. +*/ +if (page && !IS_ALIGNED (address,HPAGE_PMD_SIZE )) +return ; + pgd =pgd_offset (vma->vm_mm, address);if (!pgd_present (*pgd))return ;Signature · 1 line
2.17.1Signature · 2 lines
Wei Yang Help you, Help me
Signature · 2 lines
Wei Yang Help you, Help me
Quoted 31 lines · Wei Yang
Quoted 30 lines · Wei Yang
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched
Quoted 7 lines
Quoted 7 lines
963 195 988 40 895 78Average 948 104
So the change reduced 90% time for function
split_huge_pmd_address().
Right.
But do we have a scenario, where the performance of split_huge_pmd_address() matters? I mean, it it called as part of rmap walk, attempt to split huge PMD where we don't have huge PMD should be within noise.
Quoted 5 lines
Quoted 4 lines
For the 2nd comment, the vma check. Let me take a further look to analysis.
Thanks for Kirill's suggestion.
Quoted 8 lines
For 2nd comment, check vma could hold huge page.
You mean do this check ?
vma->vm_start <= address && vma->vm_end >= address + HPAGE_PMD_SIZEThis happens after munmap a partial of the THP range? After doing so, we can skip
split_pmdfor this case.
Okay, you are right. This kind of check would not be safe as we split_huge_pmd_address() after adjusting VMA with expectation of splitting PMD on boundary of the VMA.
Signature · 1 line
Kirill A. Shutemov
Quoted 38 lines · Kirill A. Shutemov
Quoted 37 lines · Wei Yang
Quoted 36 lines · Wei Yang
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched 963 195 988 40 895 78Average 948 104
Quoted 8 lines
Quoted 1 line
Quoted 1 line
So the change reduced 90% time for function
split_huge_pmd_address().Right.
But do we have a scenario, where the performance of
split_huge_pmd_address()matters? I mean, it it called as part of rmap walk, attempt to split huge PMD where we don't have huge PMD should be within noise.
Sorry for my poor English.
I don't catch the meaning of the last sentence. "within noise" here means non-huge PMD is an expected scenario and we could tolerate this?
Quoted 21 lines
Quoted 6 lines
Quoted 5 lines
For the 2nd comment, the vma check. Let me take a further look to analysis.
Thanks for Kirill's suggestion.
Quoted 8 lines
For 2nd comment, check vma could hold huge page.
You mean do this check ?
vma->vm_start <= address && vma->vm_end >= address + HPAGE_PMD_SIZEThis happens after munmap a partial of the THP range? After doing so, we can skip
split_pmdfor this case.Okay, you are right. This kind of check would not be safe as we
split_huge_pmd_address()after adjusting VMA with expectation of splitting PMD on boundary of the VMA.Signature · 1 line
Kirill A. Shutemov
Signature · 2 lines
Wei Yang Help you, Help me
Quoted 48 lines · Wei Yang
Quoted 38 lines · Kirill A. Shutemov
Quoted 37 lines · Wei Yang
Quoted 36 lines · Wei Yang
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched 963 195 988 40 895 78Average 948 104
Quoted 8 lines
Quoted 1 line
Quoted 1 line
So the change reduced 90% time for function
split_huge_pmd_address().Right.
But do we have a scenario, where the performance of
split_huge_pmd_address()matters? I mean, it it called as part of rmap walk, attempt to split huge PMD where we don't have huge PMD should be within noise.
Quoted 4 lines
Sorry for my poor English.
I don't catch the meaning of the last sentence. "within noise" here means non-huge PMD is an expected scenario and we could tolerate this?
Basically, I doubt that this change would bring any measurable perfromance benefits on a real workload.
Signature · 1 line
Kirill A. Shutemov
Quoted 49 lines · Kirill A. Shutemov
Quoted 48 lines · Wei Yang
Quoted 46 lines · Kirill A. Shutemov
Quoted 31 lines · Wei Yang
Quoted 30 lines · Wei Yang
Quoted 13 lines · Wei Yang
When page is not NULL, function is called by
try_to_unmap_one()withTTU_SPLIT_HUGE_PMDset. There are two cases to calltry_to_unmap_one()withTTU_SPLIT_HUGE_PMDset:*
unmap_page()
*shrink_page_list()In both case, the page passed to
try_to_unmap_one()isPageHead()of the THP. If this page's mapping address in process is notHPAGE_PMD_SIZEaligned, this means the THP is not mapped as PMD THP in this process. This could happen when we domremap()a PMD size range to an un-aligned address.Quoted 6 lines
Currently, this case is handled by following check in
__split_huge_pmd()luckily.page !=
pmd_page(*pmd)This patch checks the address to skip some work.
I am sorry to forget address Kirill's comment in 1st version.
The first one is the performance difference after this change for a PTE mappged THP.
Here is the result:(in cycle)
Before Patched
Quoted 7 lines
Quoted 7 lines
963 195 988 40 895 78Average 948 104
So the change reduced 90% time for function
split_huge_pmd_address().Right.
But do we have a scenario, where the performance of
split_huge_pmd_address()matters? I mean, it it called as part of rmap walk, attempt to split huge PMD where we don't have huge PMD should be within noise.
Quoted 8 lines
Quoted 4 lines
Sorry for my poor English.
I don't catch the meaning of the last sentence. "within noise" here means non-huge PMD is an expected scenario and we could tolerate this?
Basically, I doubt that this change would bring any measurable perfromance benefits on a real workload.
Ok, let's leave it now.
Quoted 2 lines
Signature · 1 line
Kirill A. Shutemov
Signature · 2 lines
Wei Yang Help you, Help me