Tuesday 4 October 2011

OS161 Fork - Major Difficulties

A lot of people, including myself, have been having troubles with getting fork() to work as expected. Things like TLB misses on load or write, Bus errors, and other panic codes you never want to see.

What I am going to do is go over are Major Areas that can cause problems that are very difficult to find.

sys_fork

  1.  You must copy the address space BEFORE you call thread fork other wise you have a synchronization issue.
  2. You must also copy the trapframe BEFORE you call thread fork. The is however another small issue with this. The trapframe must be on the heap not the stack so the space must be allocated using kmalloc
md_forkentry

  1. All you have to do is assign the pointer to the address space you passed in, into the thread structure. Don't worry about anything else.
  2. You now have to copy the trapframe from the heap onto the stack of the current thread which means this time you DO NOT want to use kmalloc just declare a struct NOT a pointer and copy into that location.
  3. Last you will want to increment your epc, set your retrun value to zero and make sure userland will see the return as a success (please see comment at the beginning and code at the end of mips_syscall)

That is it. There are really very few 'tricks' to fork() just a couple of hard to debug memory issues.

Feel free to put comments below I will try and answer them if they are appropriate

- FlounderingZ

3 comments:

  1. Thank you so much for these tutorials they have been a great help. Almost all of my class is using your notes as a guide.

    I have a question though, you said we should copy the trapframe when forking but we don't have access to the trapframe from our fork function. I am refering to the fork function that's defined in unistd.h. Also is that fork(void) the same as sys_fork(trapframe) if not where is each declared?

    Thank you

    ReplyDelete
  2. The declaration in unistd.h is the prototype that is exposed to user-level code.

    You will need to have a function on the kernel side that will be called from inside mips_syscall. This is where a call to the function that actually does the forking will be located. I chose to name this function sys_fork to be consistent with the existing codebase. I also chose to pass the trapframe into this function as I knew I would need it. A different implementation may have different requirements that is simply how I chose to do it. The sys_fork function would most likely be defined in syscall.h but again it could be somewhere else if you choose.

    ReplyDelete
  3. Okay, thank you for the clarification.

    ReplyDelete