Page 1 of 1

Allocating user stack during kthread_create

Posted: Wed May 19, 2010 2:40 pm
by gerryg400
Anyone implementing a microkernel with their memory manager in user space?

Assuming thread creation by calling pthread_create which is eventually a kernel call, and that the kernel doesn't have access to the memory map of the new thread, I'm just wondering how you go about creating a user stack for new threads. I've thought of a few approaches, but am wondering what others have done. Some ideas...

1. The application that is creating the new thread mallocs a stack in user space before calling pthread_create and passes the top-of-stack pointer to the kernel. I use this approach so far.

2. The code inside pthread_create does a malloc/mmap and creates the stack and passes the top-of-stack pointer to the kernel. This method hides the memory allocation from the application.

3. pthread_create does nothing and the kernel after creating the thread, puts the thread on a special waiting-for-new-stack queue that the memory manager monitors. - I don't really like this method because it's a special case.

4. The kernel doesn't create a stack and allows the new thread to fault. When the memory manager handles the fault it can create the stack. Perhaps the kernel could fake the stack fault and the MM could handle it before the thread actually runs.

5. Change my design to be a monolithic kernel.....! No.

- gerryg400

Re: Allocating user stack during kthread_create

Posted: Wed May 19, 2010 3:00 pm
by NickJohnson
Although my memory manager is in kernelspace, I use a sort of on-demand system like your #4. It doesn't cause a significant performance hit, because you need to go into kernelmode (or in your case, to the memory manager too) whether you handle the fault or do a system call anyway. It also saves memory and removes the guesswork in allocating thread stacks.

Also, it wouldn't really be a monolithic kernel if you have the memory manager in kernelspace: I've always restricted my definition of a microkernel to nothing device or format-dependent (i.e. drivers) in kernelspace. However, if you think it's better separate, more power to you.

Re: Allocating user stack during kthread_create

Posted: Wed May 19, 2010 5:51 pm
by Gigasoft
Yeah, memory management should definitely be a part of the kernel.

In my OS (well, rather, how it's going to be if I don't change my mind), when creating a thread, the caller can either specify the initial ESP, or let the system allocate a stack of a specified size. If the system allocates the stack, it automatically frees it when the thread is terminated. On thread termination, another thread can be notified so that it can free a stack that was not allocated automatically. When a program is launched, the system automatically creates a thread using parameters from the executable image.

Re: Allocating user stack during kthread_create

Posted: Wed May 19, 2010 6:20 pm
by gerryg400
Yeah, memory management should definitely be a part of the kernel.
I'm new but I'm guessing you guys have been over this before. I'll just say "Nope, memory management shouldn't be a part of the kernel". :|

Actually I don't really have a religious view either way. My memory manager lives in user space but is mapped into every memory context so that no context switch is required to send a msg to it. It is definitely part of the OS tho. In fact it is the biggest part of the OS. I think the difference between my mm and yours is probably that mine runs asynchronously with its clients while yours is synchronous. I just find most of it easier to do this way. The difficulties occur when a synchronous kernel call (like thread create) needs to do something that I've chosen to do asynchronously in user space.

Re: Allocating user stack during kthread_create

Posted: Wed May 19, 2010 6:57 pm
by NickJohnson
gerryg400 wrote:I think the difference between my mm and yours is probably that mine runs asynchronously with its clients while yours is synchronous. I just find most of it easier to do this way. The difficulties occur when a synchronous kernel call (like thread create) needs to do something that I've chosen to do asynchronously in user space.
Interesting... how exactly does it work asynchronously? Is the kernel's IPC asynchronous and used for memory management calls, or does the memory manager handle and queue calls directly because it is mapped in every address space? It seems like a strange idea, because memory management operations are usually needed immediately for a program to progress.

Re: Allocating user stack during kthread_create

Posted: Wed May 19, 2010 7:17 pm
by gerryg400
When I said the MM was asynchronous (I shouldn't have overloaded the word), I meant that the MM is a server process that runs at the 'same time' as the clients that it serves. It can handle requests in the order it chooses. If the MM were part of the kernel, I imagine that an mmap would be done synchronously in line with the kernel call and when the system call returns mmap is done.

Of course from the application point of view in my OS, mmap feels synchronous. This is because the IPC message pass is synchronous.

Does that make more sense ?

- gerryg400

Re: Allocating user stack during kthread_create

Posted: Thu May 20, 2010 9:32 am
by Gigasoft
Well, there shouldn't be a problem in having the kernel issue a memory allocation request, wait for it to complete and proceed as usual, just like an user mode application would.

But, if the memory manager runs in user mode, and must be able to run in any context, then it means that every user mode application has access to the page tables, and can therefore overwrite the system and memory belonging to other applications. Doesn't this defeat the purpose of running things in user mode?

Re: Allocating user stack during kthread_create

Posted: Thu May 20, 2010 3:28 pm
by gerryg400
My memory manager lives in user space but is mapped into every memory context so that no context switch is required to send a msg to it. It is definitely part of the OS tho.
Actually, I lied. I should say my memory manager lives in supervisor space. It runs at ring1. The point I am trying to make is that my memory manager is an application. Just like the shell or editor etc. It has a pid, main function, it can open files, do printf to sdtout etc. The differences between it an the other apps is that it's loaded into upper memory like the kernel and because it runs at ring1 its memory is protected from the other ring3 processes.