Process Scheduling
Process Scheduling
Recall: example of fork( ): Web Server Recall: How does fork() actually work in Linux?
int main() {
• Semantics are that fork()
Serial Version
// Let exited children rest in peace! – Instead, child executes in parent’s address space
while (waitpid(-1,&status,WNOHANG) > 0); Parent blocked until child calls “exec()” or exits
}
} – Child not allowed to write to the address space
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.3 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.4
Some preliminary notes on Kernel memory Linux Virtual memory map
• Many OS implementations (including linux) map parts of kernel into
every address space 0xFFFFFFFFFFFFFFFF
– Allows kernel to see into client processes 0xFFFFFFFF
128TiB
» Transferring data 896MB Kernel Kernel
1GB
» Examining state Physical Addresses 64 TiB Addresses
• In Linux, Kernel memory not generally visible to user Physical
0xC0000000
– Exception: special VDSO facility that maps kernel code into user 0xFFFF800000000000
space to aid in system calls (and to provide certain actual system
calls such as gettimeofday().
• Every physical page described by a “page” structure “Canonical Hole” Empty
– Collected together in lower physical memory Space
3GB Total
– Can be accessed in kernel virtual space User
– Linked together in various “LRU” lists Addresses 0x00007FFFFFFFFFFF
• For 32-bit virtual memory architectures:
128TiB
– When physical memory < 896MB User
» All physical memory mapped at 0xC0000000 Addresses
– When physical memory >= 896MB
» Not all physical memory mapped in kernel space all the time 0x00000000 0x0000000000000000
» Can be temporarily mapped with addresses > 0xCC000000
• For 64-bit virtual memory architectures: 32-Bit Virtual Address Space 64-Bit Virtual Address Space
– All physical memory mapped above 0xFFFF800000000000
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.5 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.6
• Many different types of allocation – Free memory: void kfree(const void *ptr);
– Important restrictions!
– SLAB allocators, per-page allocators, mapped/unmapped
» Must call with memory previously allocated through kmalloc()
interface!!!
• Many different types of allocated memory: » Must not free memory twice!
– Anonymous memory (not backed by a file, heap/stack) • Alternative: vmalloc()/vfree()
– Mapped memory (backed by a file) – Will be only contiguous in virtual address space
– No guarantee contiguous in physical RAM
• Allocation priorities » However, only devices typically care about difference
– Is blocking allowed/etc – vmalloc() may be slower than kmalloc(), since kernel must deal
with memory mappings
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.7 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.8
Allocation flags More sophisticated memory allocation (more later)
• Possible allocation type flags: • One (core) mechanism for requesting pages: everything
– GFP_ATOMIC: Allocation high-priority and must never else on top of this mechanism:
sleep. Use in interrupt handlers, top
halves, while holding locks, or other times – Allocate contiguous group of pages of size 2order bytes
cannot sleep given the specified mask:
– GFP_NOWAIT: Like GFP_ATOMIC, except call will
not fall back on emergency memory struct page * alloc_pages(gfp_t gfp_mask,
pools. Increases likely hood of failure unsigned int order)
– GFP_NOIO: Allocation can block but must not – Allocate one page:
initiate disk I/O.
struct page * alloc_page(gfp_t gfp_mask)
– GFP_NOFS: Can block, and can initiate disk I/O,
but will not initiate filesystem ops.
– Convert page to logical address (assuming mapped):
– GFP_KERNEL: Normal allocation, might block. Use in
process context when safe to sleep.
This should be default choice void * page_address(struct page *page)
– GFP_USER: Normal allocation for processes • Also routines for freeing pages
– GFP_HIGHMEM: Allocation from ZONE_HIGHMEM • Zone allocator uses “buddy” allocator that tries to
– GFP_DMA Allocation from ZONE_DMA. Use in keep memory unfragmented
combination with a previous flag • Allocation routines pick from proper zone, given flags
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.9 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.10
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.11 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.12
Message queues Shared Memory Communication
• What are they? Data 2
– Similar to the FIFO pipes, except that a tag (type) is matched Code Code
when reading/writing Stack 1 Data
» Allowing cutting in line (I am only interested in a particular type of Data
message) Heap 1 Heap
» Equivalent to merging of multiple FIFO pipes in one Heap
• Creating a message queue: Code 1 Stack
– int msgget(key_t key, int msgflag);
Stack
Stack 2 Shared
– Key can be any large number. But to avoiding using conflicting Shared
keys in different programs, use ftok() (the key master). Data 1
» key_t ftok(const char *path, int id); Prog 2
Prog 1
• Path point to a file that the process can stat Heap 2 Virtual
• Id: project ID, only the last 8 bits are used Virtual
• Message queue operations Address Code 2 Address
int msgget(key_t, int flag) Space 1 Space 2
int msgctl(int msgid, int cmd, struct msgid_ds *buf) Shared
int msgsnd(int msgid, const void *ptr, size nbytes, int flag);
int msgrcv(int msgid, void *ptr, size_t nbytes, long type, int flag); • Communication occurs by “simply” reading/writing
to shared address page
• Performance advantage is no longer there in newer – Really low overhead communication
systems (compared with pipe)
– Introduces complex synchronization problems
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.13 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.14
Example:
key_t key;
int shmid;
char *data; • Earlier, we talked about the life-cycle of a thread
– Active threads work their way from Ready queue to
key = ftok("<somefile>", ‘A'); Running to various waiting queues.
shmid = shmget(key, 1024, 0644); • Question: How is the OS to decide which of several
data = shmat(shmid, (void *)0, 0); tasks to take off a queue?
– Obvious queue to worry about is ready queue
shmdt(data); – Others can be scheduled as well, however
• Scheduling: deciding which threads are given access
Flags: SHM_RDONLY, SHM_REMAP to resources from moment to moment
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.17 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.18
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.25 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.26
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.27 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.28
Correctness for systems with concurrent threads Interactions Complicate Debugging
• If dispatcher can schedule threads in any way, • Is any program truly independent?
programs must work under all circumstances – Every process shares the file system, OS resources,
– Can you test for this? network, etc
– How can you know if your program works? – Extreme example: buggy device driver causes thread A to
• Independent Threads: crash “independent thread” B
– No state shared with other threads • You probably don’t realize how much you depend on
– Deterministic Input state determines results reproducibility:
– Reproducible Can recreate Starting Conditions, I/O – Example: Evil C compiler
– Scheduling order doesn’t matter (if switch() works!!!) » Modifies files behind your back by inserting errors into C
program unless you insert debugging code
• Cooperating Threads: – Example: Debugging statements can overrun stack
– Shared State between multiple threads
• Non-deterministic errors are really difficult to find
– Non-deterministic
– Example: Memory layout of kernel+user programs
– Non-reproducible
» depends on scheduling, which depends on timer/other things
• Non-deterministic and Non-reproducible means that » Original UNIX had a bunch of non-deterministic errors
bugs can be intermittent
– Example: Something which does interesting I/O
– Sometimes called “Heisenbugs”
» User typing of letters used to help generate secure keys
2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.29 2/9/14 Kubiatowicz CS194-24 ©UCB Fall 2014 Lec 6.30
Summary
• Linux Memory Map
– Portions of virtual memory reserved for kernel
» 32-bit machines: memory < 896 mapped at 0xC0000000
» 64-bit machines: all memory mapped at 0xFFFF800000000000
– Kernel memory not necessarily visible to user in usermode
• Linux Kernel Memory Details
– kmalloc()/kfree(): Kernel versions of normal malloc
– alloc_pages(): Allocate pages directly from SLAB allocator
– Flags specify terms of allocation, e.g.:
» GFP_KERNEL: Normal allocation, might block.
» GFP_USER: Normal allocation for process space
• Interprocessor Communication:
– Message Queues/Shared Memory/Others
• Scheduling
– Non-Realtime Goals: Throughput, Latency, Fairness
– Realtime Goals: Meet deadlines, other QoS constraints