Q: behaviour of mlockall(MCL_FUTURE) and VM_GROWSDOWN segments
Quoted 3 lines · Andrew Morton
So in this case, the behaviour I would prefer is
MCL_FUTUREfor
all vma's *except* the stack. Stack pages should be locked
only when they are faulted in. Hard call.
There is just one problem: linuxthread stacks are just ordinary mappings and they are in no way special to the kernel; they aren't VM_GROWSDOWN. You would need to add a way to the kernel first to tag the linux thread stacks in a way that is recognizable to mlockall and then do that from linuxthreads.
I think for the normal stack - real VM_GROWSDOWN segments - mlockall already does the right thing.
-Andi
Quoted 7 lines · Andi Kleen
Quoted 3 lines · Andrew Morton
So in this case, the behaviour I would prefer is
MCL_FUTUREfor
all vma's *except* the stack. Stack pages should be locked
only when they are faulted in. Hard call.
Quoted 8 lines
There is just one problem: linuxthread stacks are just ordinary mappings and they are in no way special to the kernel; they aren't
VM_GROWSDOWN. You would need to add a way to the kernel first to tag the linux thread stacks in a way that is recognizable to mlockall and then do that from linuxthreads.I think for the normal stack - real
VM_GROWSDOWNsegments - mlockall already does the right thing.
hmm.. So I wonder what changed between 2.4.7 and 2.4.15 which unbroke MCL_FUTURE.
I suspect we can fix the problem by running mlockall(MCL_FUTURE) and then an explicit munlock() of the stack area.
-
Quoted 6 lines · Andi Kleen
Quoted 3 lines · Andrew Morton
So in this case, the behaviour I would prefer is
MCL_FUTUREfor
all vma's *except* the stack. Stack pages should be locked
only when they are faulted in. Hard call.
Quoted 8 lines
There is just one problem: linuxthread stacks are just ordinary mappings and they are in no way special to the kernel; they aren't
VM_GROWSDOWN. You would need to add a way to the kernel first to tag the linux thread stacks in a way that is recognizable to mlockall and then do that from linuxthreads.I think for the normal stack - real
VM_GROWSDOWNsegments - mlockall already does the right thing.
it doesn't (of course depends "what's the right thing"), and that's why Manfred is asking after I asked him if he was really sure the API was the right one, but as said to him, something is wrong with the kernel too somehow, either we remove mark_page_present from find_extend_vma, or we add it to the page fault handler too.
What the current kernel is doing with page faults, is to fault in only the touched pages, not the pages in between as well, this isn't a security concern because the faulted in pages won't be swapped out, but it may matter for some RT app, OTOH the RT apps would better memset the whole stack they need before assuming they won't get page faults, first of all because of all other kernels out there (this is what I mean with a matter of API).
I guess it is cleaner if a VM_LOCKED vma has all its pages allocated between vm_start and vm_end, so I guess adding the mark_page_present in do_page_fault as suggested by Manfred is ok.
Andrea
Quoted 1 line · Andrea Arcangeli
it doesn't (of course depends "what's the right thing"), and that's why
I think it does. Allocating all possible in future allocated pages is just not possible for VM_GROWSDOWN, because the stack has really no suitable limit (other than rlimits, which are far too big to mlock them)
BTW expand_stack seems to have a small bug: it adds to mm->locked_vm the complete offset from last vm_start; if it covers more than one page the locked_vm value will be too large.
Quoted 7 lines
What the current kernel is doing with page faults, is to fault in only the touched pages, not the pages in between as well, this isn't a security concern because the faulted in pages won't be swapped out, but it may matter for some RT app, OTOH the RT apps would better memset the whole stack they need before assuming they won't get page faults, first of all because of all other kernels out there (this is what I mean with a matter of API).
For the stack they can get minor faults anyways when they allocate new stack space below ESP. There is no good way to fix that from the kernel; the application has to preallocate its memory on stack. I think it's reasonable if it does the same for holes on the stack.
-Andi
Quoted 6 lines · Andi Kleen
For the stack they can get minor faults anyways when they allocate new stack space below ESP. There is no good way to fix that from the kernel; the application has to preallocate its memory on stack. I think it's reasonable if it does the same for holes on the stack.
Ok, everyone agrees that mlockall() should not grow VM_GROWSDOWN segments to their maximum size.
Should the page fault handler fill the hole created by
void * grow_stack(void)
{
char data[100000];
data[0] = '0';
return data;
}The principle of least surprise would mean filling holes, but OTHO sane apps would use memset(data,0,sizeof(data)).
--
Manfred
Quoted 7 lines · Andi Kleen
Quoted 1 line · Andrea Arcangeli
it doesn't (of course depends "what's the right thing"), and that's why
I think it does. Allocating all possible in future allocated pages is just not possible for
VM_GROWSDOWN, because the stack has really no suitable limit (other than rlimits, which are far too big to mlock them)
the user asked for VM_LOCKED vma, if he asks for that and he faults too low on the stack with big holes in between that's his mistake. And anyways ptrace just faults in all the intermediate pages just now, so it is definitely possible (we provide different userspace API from ptrace/map_user_kiobuf and page-fault at the moment).
Quoted 13 lines
BTW
expand_stackseems to have a small bug: it adds tomm->locked_vmthe complete offset from lastvm_start; if it covers more than one page thelocked_vmvalue will be too large.Quoted 7 lines
What the current kernel is doing with page faults, is to fault in only the touched pages, not the pages in between as well, this isn't a security concern because the faulted in pages won't be swapped out, but it may matter for some RT app, OTOH the RT apps would better memset the whole stack they need before assuming they won't get page faults, first of all because of all other kernels out there (this is what I mean with a matter of API).
Quoted 2 lines
For the stack they can get minor faults anyways when they allocate new stack space below ESP. There is no good way to fix that from the kernel; the
the only case here is when the app knows how much stack it will need to use, without faulting in the holes, it will have to memset the whole region of stack the it wants to be atomic. If instead the kernel also fault-in the holes (like map_user_kiobuf/ptrace/get_user_pages just does in 2.4) the app will only need to touch the lowest virtual address of stack it needs as atomic.
I don't see any real problem either ways, it must be simply a well defined API.
Then the user will know if he can touch one byte and the kernel fills the holes automatically, or if he has to do the whole memset.
Quoted 9 lines
application has to preallocate its memory on stack. I think it's reasonable if it does the same for holes on the stack.
(quoted diff) +0
-2-Andi -To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Andrea
Quoted 9 lines · Manfred Spraul
Quoted 6 lines · Andi Kleen
For the stack they can get minor faults anyways when they allocate new stack space below ESP. There is no good way to fix that from the kernel; the application has to preallocate its memory on stack. I think it's reasonable if it does the same for holes on the stack.
Ok, everyone agrees that
mlockall()should not growVM_GROWSDOWNsegments to their maximum size.
Ah, definitely. I must have misunderstood something in the discussion sorry, I thought we were just discussiong the below issue, and I completly missed the "maximum size" one.
All I was trying to find out here, was about the intermediate pages between vm_start and vm_end of a VM_GROWSDOWN|VM_LOCKED vma, exactly your example below.
Quoted 11 lines
Should the page fault handler fill the hole created by
void *
grow_stack(void){ char data[100000]; data[0] = '0'; return data; }The principle of least surprise would mean filling holes, but OTHO sane apps would use memset(data,0,sizeof(data)).
yep.
Andrea