Skip to contentSkip to conversation

a question about mlockall() and mprotect()

RFC Xishi Qiu 3 participants 13 messages Sep 26, 2017 – Oct 10, 2017

Subsystems (2)
lore
Share & tools
lore

Xishi Qiu

author
#0 lore raw

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p, then mm_populate -> get_user_pages will not alloc memory.

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

Thanks,
Xishi Qiu

#1 lore raw
Quoted 2 lines · Xishi Qiu

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p,

not sure what you mean here. apply_mlockall_flags will set the flag on all vmas except for special mappings (mlock_fixup). This phase will cause that memory reclaim will not free already mapped pages in those vmas (see page_check_references and the lazy mlock pages move to unevictable LRUs).

Quoted 1 line

then mm_populate -> get_user_pages will not alloc memory.

mm_populate all the vmas with pages. Well there are certainly some constrains - e.g. memory cgroup hard limit might be hit and so the faulting might fail.

Quoted 6 lines

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

But we do not report the failure because any failure past apply_mlockall_flags would be tricky to handle. We have already dropped the mmap_sem lock so some other address space operations could have interfered.

Quoted 5 lines

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

I do not understand your question but if you are asking how to get pages to map your vmas then touching that area will fault the memory in.

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>
author
#2 lore raw
Quoted 28 lines · Michal Hocko
Quoted 2 lines · Xishi Qiu

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p,

not sure what you mean here. apply_mlockall_flags will set the flag on all vmas except for special mappings (mlock_fixup). This phase will cause that memory reclaim will not free already mapped pages in those vmas (see page_check_references and the lazy mlock pages move to unevictable LRUs).

Quoted 1 line

then mm_populate -> get_user_pages will not alloc memory.

mm_populate all the vmas with pages. Well there are certainly some constrains - e.g. memory cgroup hard limit might be hit and so the faulting might fail.

Quoted 6 lines

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

But we do not report the failure because any failure past apply_mlockall_flags would be tricky to handle. We have already dropped the mmap_sem lock so some other address space operations could have interfered.

Quoted 8 lines
Quoted 5 lines

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

I do not understand your question but if you are asking how to get pages to map your vmas then touching that area will fault the memory in.

Hi Michal,

syscall mlockall() will first apply the VM_LOCKED to the vma, then call mm_populate() to map the vmas.

mm_populate
populate_vma_page_range
__get_user_pages
check_vma_flags
And the above path maybe return -EFAULT in some case, right?

If we call mprotect() to change the prot of vma, just let check_vma_flags() return 0, then we will get the mlocked pages in following page-fault, right?

My question is that, shall we map the vmas immediately when
the prot changed? If we should map it immediately, who(kernel, glibc, user) do this step?

Thanks,
Xishi Qiu

#3 lore raw
Quoted 50 lines · Xishi Qiu
Quoted 28 lines · Michal Hocko
Quoted 2 lines · Xishi Qiu

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p,

not sure what you mean here. apply_mlockall_flags will set the flag on all vmas except for special mappings (mlock_fixup). This phase will cause that memory reclaim will not free already mapped pages in those vmas (see page_check_references and the lazy mlock pages move to unevictable LRUs).

Quoted 1 line

then mm_populate -> get_user_pages will not alloc memory.

mm_populate all the vmas with pages. Well there are certainly some constrains - e.g. memory cgroup hard limit might be hit and so the faulting might fail.

Quoted 6 lines

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

But we do not report the failure because any failure past apply_mlockall_flags would be tricky to handle. We have already dropped the mmap_sem lock so some other address space operations could have interfered.

Quoted 8 lines
Quoted 5 lines

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

I do not understand your question but if you are asking how to get pages to map your vmas then touching that area will fault the memory in.

Hi Michal,

syscall mlockall() will first apply the VM_LOCKED to the vma, then call mm_populate() to map the vmas.

mm_populate
populate_vma_page_range
__get_user_pages
check_vma_flags
And the above path maybe return -EFAULT in some case, right?

Quoted 3 lines

If we call mprotect() to change the prot of vma, just let check_vma_flags() return 0, then we will get the mlocked pages in following page-fault, right?

Any future page fault to the existing vma will result in the mlocked page. That is what VM_LOCKED guarantess.

Quoted 3 lines

My question is that, shall we map the vmas immediately when
the prot changed? If we should map it immediately, who(kernel, glibc, user) do this step?

This is still very fuzzy. What are you actually trying to achieve?

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>
author
#4 lore raw
Quoted 55 lines · Michal Hocko
Quoted 50 lines · Xishi Qiu
Quoted 28 lines · Michal Hocko
Quoted 2 lines · Xishi Qiu

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p,

not sure what you mean here. apply_mlockall_flags will set the flag on all vmas except for special mappings (mlock_fixup). This phase will cause that memory reclaim will not free already mapped pages in those vmas (see page_check_references and the lazy mlock pages move to unevictable LRUs).

Quoted 1 line

then mm_populate -> get_user_pages will not alloc memory.

mm_populate all the vmas with pages. Well there are certainly some constrains - e.g. memory cgroup hard limit might be hit and so the faulting might fail.

Quoted 6 lines

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

But we do not report the failure because any failure past apply_mlockall_flags would be tricky to handle. We have already dropped the mmap_sem lock so some other address space operations could have interfered.

Quoted 8 lines
Quoted 5 lines

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

I do not understand your question but if you are asking how to get pages to map your vmas then touching that area will fault the memory in.

Hi Michal,

syscall mlockall() will first apply the VM_LOCKED to the vma, then call mm_populate() to map the vmas.

mm_populate
populate_vma_page_range
__get_user_pages
check_vma_flags
And the above path maybe return -EFAULT in some case, right?

Quoted 3 lines

If we call mprotect() to change the prot of vma, just let check_vma_flags() return 0, then we will get the mlocked pages in following page-fault, right?

Quoted 8 lines

Any future page fault to the existing vma will result in the mlocked page. That is what VM_LOCKED guarantess.

Quoted 3 lines

My question is that, shall we map the vmas immediately when
the prot changed? If we should map it immediately, who(kernel, glibc, user) do this step?

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

#5 lore raw
Quoted 1 line · Xishi Qiu

On 2017/9/26 17:02, Michal Hocko wrote:

[...]

Quoted 3 lines
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

This should be the case normally. Except when mm_populate fails which can happen e.g. when running inside a memcg with the hard limit configured. Is there any other unexpected failure scenario you are seeing?

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>
author
#6 lore raw
In reply to Xishi Qiu
Quoted 60 lines · Xishi Qiu
Quoted 58 lines · Michal Hocko
Quoted 50 lines · Xishi Qiu
Quoted 28 lines · Michal Hocko
Quoted 2 lines · Xishi Qiu

When we call mlockall(), we will add VM_LOCKED to the vma, if the vma prot is ---p,

not sure what you mean here. apply_mlockall_flags will set the flag on all vmas except for special mappings (mlock_fixup). This phase will cause that memory reclaim will not free already mapped pages in those vmas (see page_check_references and the lazy mlock pages move to unevictable LRUs).

Quoted 1 line

then mm_populate -> get_user_pages will not alloc memory.

mm_populate all the vmas with pages. Well there are certainly some constrains - e.g. memory cgroup hard limit might be hit and so the faulting might fail.

Quoted 6 lines

I find it said "ignore errors" in mm_populate()
static inline void mm_populate(unsigned long addr, unsigned long len)

{
	/* Ignore errors */
	(void) __mm_populate(addr, len, 1);
}

But we do not report the failure because any failure past apply_mlockall_flags would be tricky to handle. We have already dropped the mmap_sem lock so some other address space operations could have interfered.

Quoted 8 lines
Quoted 5 lines

And later we call mprotect() to change the prot, then it is still not alloc memory for the mlocked vma.

My question is that, shall we alloc memory if the prot changed, and who(kernel, glibc, user) should alloc the memory?

I do not understand your question but if you are asking how to get pages to map your vmas then touching that area will fault the memory in.

Hi Michal,

syscall mlockall() will first apply the VM_LOCKED to the vma, then call mm_populate() to map the vmas.

mm_populate
populate_vma_page_range
__get_user_pages
check_vma_flags
And the above path maybe return -EFAULT in some case, right?

Quoted 3 lines

If we call mprotect() to change the prot of vma, just let check_vma_flags() return 0, then we will get the mlocked pages in following page-fault, right?

Any future page fault to the existing vma will result in the mlocked page. That is what VM_LOCKED guarantess.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

My question is that, shall we map the vmas immediately when
the prot changed? If we should map it immediately, who(kernel, glibc, user) do this step?

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Thanks,
Xishi Qiu

Quoted 3 lines

.

#7 lore raw
Quoted 9 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Vlastimil

#8 lore raw
Quoted 7 lines · Vlastimil Babka
Quoted 6 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Quoted 6 lines
Quoted 3 lines

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time mlockall and then later mprotect it something else and want to fault all that memory at the mprotect time?

So basically to do
---

mm/mprotect.c +1 -1
index 6d3e2f082290..b665b5d1c544 100644
@@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 	 * fault on access.
 	 */
-	if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+	if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
 			(newflags & VM_WRITE)) {
 		populate_vma_page_range(vma, start, end, NULL);
 	}
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>
author
#9 lore raw
Quoted 27 lines · Michal Hocko
Quoted 7 lines · Vlastimil Babka
Quoted 6 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Quoted 6 lines
Quoted 3 lines

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time mlockall and then later mprotect it something else and want to fault all that memory at the mprotect time?

So basically to do
---

mm/mprotect.c +0 -0
index 6d3e2f082290..b665b5d1c544 100644

mm/mprotect.c mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, · line 375

Quoted 8 lines
mm/mprotect.c +1 -1
@@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 	 * fault on access.
 	 */
-	if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+	if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
 			(newflags & VM_WRITE)) {
 		populate_vma_page_range(vma, start, end, NULL);
 	}

Hi Michal,

My kernel is v3.10, and I missed this code, thank you reminding me.

Thanks,
Xishi Qiu

#10 lore raw
Quoted 40 lines · Xishi Qiu
Quoted 27 lines · Michal Hocko
Quoted 7 lines · Vlastimil Babka
Quoted 6 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Quoted 6 lines
Quoted 3 lines

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time mlockall and then later mprotect it something else and want to fault all that memory at the mprotect time?

So basically to do
---

mm/mprotect.c +0 -0
index 6d3e2f082290..b665b5d1c544 100644

mm/mprotect.c mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, · line 375

Quoted 8 lines
mm/mprotect.c +1 -1
@@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 	 * fault on access.
 	 */
-	if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+	if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
 			(newflags & VM_WRITE)) {
 		populate_vma_page_range(vma, start, end, NULL);
 	}

Hi Michal,

Quoted 1 line

My kernel is v3.10, and I missed this code, thank you reminding me.

I guess I didn't get your answer. Does the above diff resolves your problem?

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>
author
#11 lore raw
Quoted 41 lines · Michal Hocko
Quoted 40 lines · Xishi Qiu
Quoted 27 lines · Michal Hocko
Quoted 7 lines · Vlastimil Babka
Quoted 6 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Quoted 6 lines
Quoted 3 lines

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time mlockall and then later mprotect it something else and want to fault all that memory at the mprotect time?

So basically to do
---

mm/mprotect.c +0 -0
index 6d3e2f082290..b665b5d1c544 100644

mm/mprotect.c mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, · line 375

Quoted 8 lines
mm/mprotect.c +1 -1
@@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 	 * fault on access.
 	 */
-	if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+	if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
 			(newflags & VM_WRITE)) {
 		populate_vma_page_range(vma, start, end, NULL);
 	}

Hi Michal,

Quoted 4 lines
Quoted 1 line

My kernel is v3.10, and I missed this code, thank you reminding me.

I guess I didn't get your answer. Does the above diff resolves your problem?

Hi Michal,

This upstream patch 36f881883c57941bb32d25cea6524f9612ab5a2c has already resolve my problem, thank you for your attention.

Thanks,
Xishi Qiu

#12 lore raw
Quoted 45 lines · Xishi Qiu
Quoted 43 lines · Michal Hocko
Quoted 41 lines · Xishi Qiu
Quoted 27 lines · Michal Hocko
Quoted 7 lines · Vlastimil Babka
Quoted 6 lines · Xishi Qiu
Quoted 4 lines · Xishi Qiu
Quoted 1 line

This is still very fuzzy. What are you actually trying to achieve?

I don't expect page fault any more after mlock.

Quoted 6 lines
Quoted 3 lines

Our apps is some thing like RT, and page-fault maybe cause a lot of time, e.g. lock, mem reclaim ..., so I use mlock and don't want page fault any more.

Why does your app then have restricted mprotect when calling mlockall() and only later adjusts the mprotect?

Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time mlockall and then later mprotect it something else and want to fault all that memory at the mprotect time?

So basically to do
---

mm/mprotect.c +0 -0
index 6d3e2f082290..b665b5d1c544 100644

mm/mprotect.c mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, · line 375

Quoted 8 lines
mm/mprotect.c +1 -1
@@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
 	 * Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
 	 * fault on access.
 	 */
-	if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
+	if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
 			(newflags & VM_WRITE)) {
 		populate_vma_page_range(vma, start, end, NULL);
 	}

Hi Michal,

My kernel is v3.10, and I missed this code, thank you reminding me.

Quoted 7 lines
Quoted 2 lines

I guess I didn't get your answer. Does the above diff resolves your problem?

Hi Michal,

This upstream patch 36f881883c57941bb32d25cea6524f9612ab5a2c has already resolve my problem, thank you for your attention.

OK, fair enough. But is does it make sense to extend this behavior to shared mappings as well?

Signature · 2 lines
Michal Hocko
SUSE Labs