Suspension exercises

Yield mechanisms

To return from a timer interrupt (INT_IRQ + INT_TIMER in, the kernel calls proc::yield_noreturn(). Change it to call proc::yield() instead.

To return from a sys_yield system call (the SYSCALL_YIELD case in, the kernel calls proc::yield(). Change it to call proc::yield_noreturn() instead.

A synchronization bug

What potential bug was addressed by commit d12e98cdb959bb9cdb85fc8e1b0878733026388e? Describe a possible execution of the old code that could violate some kernel invariant or otherwise cause a problem.

Red zone

The Chickadee kernel must be compiled with the GCC flag -mno-red-zone, which disables the x86-64 red zone, a feature of the System V AMD64 ABI (Application Binary Interface). Describe what the -mno-red-zone flag does, and why the Chickadee kernel must be compiled with that flag.

Processor affinity and CPU migration

Multiprocessor operating systems support notions of processor affinity and CPU migration, in which tasks (including process threads and kernel tasks) switch from processor to processor as they run. This can be important for load balancing—maybe all the threads on processor 0 happen to exit at about the same time, leaving processor 0 idle and the other processors oversubscribed—so a good kernel scheduler will proactively migrate tasks to mitigate this imbalance. There are also system calls that manage CPU placement directly, such as sched_setaffinity.

But moving a task from one CPU to another is harder than it might appear, because of synchronization invariants. It’s especially difficult because at the same moment as a kernel task is changing its affinity from one CPU to another, a different task might be trying to schedule the first task on its original home CPU!

Design a system-call-initiated CPU migration for Chickadee. Specifically, describe the implementation of a sys_sched_setcpu(pid_t p, int cpu) system call, which should work as follows:

  1. If p != 0 && p != current()->id_, then return an EPERM error (you’ll fix this in the next exercise).

  2. If cpu < 0 || cpu >= ncpu, then return an EINVAL error.

  3. Otherwise, the system call returns 0 and the calling thread (process) next executes on CPU cpu. That is, when the system call returns 0, the unprivileged process code is executing on CPU cpu.

Migrating other processes

Extend your sys_sched_setcpu design so processes can change other processes’ CPU placements (that is, support p != 0 && p != current()->id_). Again, your implementation must obey all Chickadee invariants and should not cause undefined behavior.

Our design of this feature does not add any new proc members, but it does add new invariants, and it changes one of the invariants we added above.