Process Control Block in Linux

How OS manages the process control block associated with a process?

Your operating-system course seems to be the classic kind of course where the author gives you information that is not always true with terminology that is not used everywhere and confusing. Overall, os design will be different based on where the os will run and what are its uses. Every os development team will have different terminology for different things. Some data structures you learn about might not be used at all.

With that said, whether there is a kernel stack and a user stack, where the registers are stored, where the PCB is stored, etc, is so unimportant and varied that it isn't information that an os course should even mention. The course should only mention that the information should be saved somewhere.

In general, the Linux kernel has one stack for user mode and one stack for kernel mode. It will also have one stack for interrupts for each core (not tied to one process). On Linux, the process has one PCB but, the kernel works on threads. Each thread belonging to the same process share the same virtual address space. The Linux kernel will tie each process to one core. This is due to the cores proximity to some portion of physical memory (called NUMA on x86-64). The ACPI tables give information on which range of physical memory is closer to a certain core. If the kernel wanted to change a thread's core, it would make its execution slower because its memory would have been allocated in the NUMA node of another core.

The virtual address space (VAS) of modern 64 bits CPUs is enormous (more than 200k GB). All threads have access to its bottom half because the kernel reserves the top half. The instructions of threads and the kernel contain virtual addresses that will be translated by the page tables. The kernel's job is to make sure that the page tables translate virtual addresses to available physical memory. For example, on a computer with 8GB of RAM, the translations must land below 8GB. There is also the NUMA node which needs to be considered.

On Linux, the PCB is thus stored in the top half of the VAS. On x86-64, the top half of the VAS is made global by switching flags in the page tables. This means that, when the kernel changes the CR3 register (the register pointing to the first page table level for x86), this portion of the TLB (translation cache) is not flushed. There is also PCID (process IDs) support in modern TLBs.

If you have a bunch of ready threads but not enough cores to run them, you can use timers that raise interrupts when a time slice has elapsed.

The kernel stack is also stored in the top half of the VAS. Where the registers are saved is really unimportant and is a basic design decision. The PCB stores information on the portion of the VAS that is allocated for a certain process and its corresponding physical counterpart. The remainder of the VAS is made non-present in the page tables by switching a flag. If a thread attempts to read, write or execute there, the kernel kills it (a segfault on Linux).

Process Control Block

From what I understand in Linux, PCB or Process Descriptors are dynamically allocated by the kernel and cannot directly be read from user-space.

IBM's developerWorks library has a nice article which shows you how to create a kernel module for Linux and access task_struct struct.

http://www.ibm.com/developerworks/linux/library/l-linux-process-management/index.html

Hope this helps.


edit: task_struct as defined in Linux v2.6.37 : http://lxr.linux.no/#linux+v2.6.37/include/linux/sched.h#L1182

Courtesy of google. :)



Related Topics



Leave a reply



Submit