Link Search Menu Expand Document

Introduction

Due by 11:59 PM on Sunday, Nov 08

Introduction

In the second part of project3 we will be providing you with the implementation to a kernel IPC system, similar to the one you had to implement for project 2. Much like project 2 and project 3 - part1, there is no synchronization to be seen anywhere. It’s is your job to add any locks required to this system. You will also have to implement one of its methods from scratch, including synchronization. Before we get into the system however, we will go over some information on synchronization as well as some useful resources.

You can find your repository at https://github.com/umbc-cmsc421-fa2020/project3-part2-yourGITusername and you can clone it from git@github.com:umbc-cmsc421-fa2020/project3-part2-yourGITusername.git, as you’ve done for project0 and project 2.

  • Unreliable Guide to Locking This is the kernel's quick documentation on locks. You can find more information in the source itself.
  • linux-insidesThis link includes a wealth of information on the linux kernel. Chances are that most of your questions have some kind of an answer in here.

Use these resources. They are not here to fill up the webpage

Requirements

For the purposed of this assignment you should NOT attempt to create your own locks. For instance you should not use the pseudocode in your book to attempt to create a mutex. You should use the primitives and functions provided by the kernel itself. For this assignment you are expected to:

  • Provide a synchronization solution for the given system
  • Implement the read systemcall, including any locking required
  • Test that implementation to ensure no deadlocks under stress and multiple threads.
  • Provide a report similar to the one of part 1 answering the following questions:
    1. What were the shared elements you had to protect/synchronize access to? How did you identify them?
    2. How did you identify your critical sections? What kind of code did you include/exclude from the sections? (You can be a bit generic here. You do not need to talk about each function individually).
    3. Describe the primitive(s) you used. Justify your choice(s).
    4. Anything else you would like to discuss. Suggestions for this section: Testing approach and difficulties. Your implementation of read and any difficulties you encountered there.

Locking

The idea of locking and synchronization is to ensure that sections of critical code are executed in their entirety “without interruption”. Notice the quotes there. There is no way to make that happen, other than crippling your operating system. As such, the idea is that even if execution gets interrupted nobody else can start their critical section. Naturally there are exceptions to that as well, the read-writer problem for example. We cannot possibly cover everything here so you should refer back to your book for more in-depth explanations.

As with most things in the kernel, locking is gonna be harder that what you did in part1. For instance, if you deadlock your kernel you whole vm will freeze. In that case you must restart your vm. There is also another layer of complexity between sleeping and non-sleeping locks. A sleeping lock means that the execution context can go to sleep while the lock is held. Going to sleep can happen for a myriad of reasons. One example is that kmalloc needs time to do the allocation and move things around, therefore the thread calling it goes to sleep. If you recall, the flags for kmalloc referenced something similar. Another case would be during user-space access like copy_to_user. You can refer to the kernel documentation about which functions can and cannot sleep. Then there is always the case of the userspace program that called the systemcall getting interrupted. Therefore, you cannot call such a function with a non-sleep lock.

While the reader/writer problem is still a potentially very relevant problem to your assignment, please avoid using rwlock_t, unless you know and understand exactly what you are doing. There are other primitives that also deal with readers and writers.

Another issue to consider is that the longer you keep a lock, the longer you delay operation of other threads/programs. Meaning you should try to minimize the time you keep a lock, and you should always remember to release a lock. You should also increase the core count of your VM to at least 2, if it is allowed by your hardware. It will make your life a lot easier.