Kernel Synchronization with material from Understanding the Linux

  • Slides: 18
Download presentation
Kernel Synchronization with material from Understanding the Linux Kernel (O’Reilly) 1

Kernel Synchronization with material from Understanding the Linux Kernel (O’Reilly) 1

Synchronization In The Kernel Past lectures: Ø Synchronization constructs Today’s lecture: Ø Ø What

Synchronization In The Kernel Past lectures: Ø Synchronization constructs Today’s lecture: Ø Ø What does this stuff look like in an OS? We have source code for Linux… We mostly run on x 86 platforms Lets look at some specifics. 2

Disabling Interrupts Key observations: Ø On a uni-processor, an operation is atomic if no

Disabling Interrupts Key observations: Ø On a uni-processor, an operation is atomic if no contextswitch is allowed in the middle of the operation Ø Context switch occurs because of: Internal events: system calls and exceptions External events: interrupts Ø Mutual exclusion can be achieved by preventing context switch Prevention of context switch Ø Eliminate internal events: easy (under program control) Ø Eliminate external events: disable interrupts Hardware delays the processing of interrupts until interrupts are enabled 3

Lock Implementation: A Naïve Solution Lock: : Acquire() { disable interrupts; } Lock: :

Lock Implementation: A Naïve Solution Lock: : Acquire() { disable interrupts; } Lock: : Release() { enable interrupts; } Will this work on a uni-processor? What is wrong with this solution? Ø Once interrupts are disabled, the thread can’t be stopped Can starve other threads Ø Critical sections can be arbitrarily long Can’t bound the amount of time needed to respond to interrupts But this is used all over the place in uniprocessor OSes to do short tasks. It is a large source of bugs. What would typical failure conditions be? 4

Disabling Interrupts in Linux Usually some small number of interrupt levels, statically assigned (e.

Disabling Interrupts in Linux Usually some small number of interrupt levels, statically assigned (e. g. , reset = 0, timer = 1, network = 3, disk = 4, software = 7) Ø When you “disable interrupts” you disable them for your level and higher. Ø When you reenable interrupts, you need to do so at the previous level. Ø Where do you store the level in the meantime? A. Local variable B. Global variable C. Hardware register unsigned long flags; local_irq_save( flags ); // Disable & save do_whatever; local_irq_restore( flags ); // Reenable 5

Using Locks Correctly Make sure to release your locks along every possible execution path.

Using Locks Correctly Make sure to release your locks along every possible execution path. unsigned long flags; local_irq_save( flags ); // Disable & save … if(something. Bad) { local_irq_restore( flags ); return ERROR_BAD_THING; } … local_irq_restore( flags ); // Reenable return 0; 6

Entering Linux An OS is a server that responds to requests, from user code

Entering Linux An OS is a server that responds to requests, from user code and from devices. How to enter the Linux kernel Ø int 0 x 80, which is the system call instruction on the x 86 by convention. Ø External device sends a signal to a programmable interrupt controller (PIC) by using an IRQ (interrupt request) line, and that interrupt is enabled. Ø A process in kernel mode causes a page fault. Ø A process in a multi-processor system executing in kernel mode raises an inter-processor interrupt. Interrupt, exception, or softirq handling can interrupt a process running in kernel mode, but when the handler terminates, the kernel control path of the process resumes. 7

Linux Synchronization Primitives Technique Description Scope Atomic Operation Atomic read-modify-write instruction All CPUs Memory

Linux Synchronization Primitives Technique Description Scope Atomic Operation Atomic read-modify-write instruction All CPUs Memory barrier Avoid instruction re-ordering Local CPU Spin lock Lock with busy wait (readers/writers spin locks) All CPUs Semaphore Lock with blocking wait (R/W semaphores) All CPUs Local interrupt disable Forbid interrupt handling on single CPU Local softirq disable Forbid deferrable function handling on a single CPU Local CPU Global interrupt disable Forbid interrupt and softirq handling on all CPUs All CPUs 8

Scope of Synch Primitives The test&set instruction is local to a single CPU in

Scope of Synch Primitives The test&set instruction is local to a single CPU in a multi-CPU system. Ø A. True Ø B. False 9

Atomic Operations Assembly language instructions that make 0 or 1 aligned memory access (a

Atomic Operations Assembly language instructions that make 0 or 1 aligned memory access (a 32 -bit aligned access has the last 2 address bits equal to zero). Read-modify-write instructions (like inc and dec) with the lock prefix. Locks the memory bus. Linux provides wrappers for these operations. Ø atomic_set(v, i) sets *v=i Ø atomic_inc_and_test(v) Add 1 to *v and return 1 if value is now zero, 0 otherwise. 10

Memory Barriers Compiler reorders your memory accesses. Memory barrier says, “wait here until all

Memory Barriers Compiler reorders your memory accesses. Memory barrier says, “wait here until all outstanding memory operations have completed. ” rmb() expands to asm volatile(“lock; addl $0, 0(%%esp)”: : : ”memory”); Ø volatile – disables compiler reorder of instruction Ø memory – forces compiler to assume any RAM can change from this instruction. Ø lock prefix locks memory bus, and requires all previous reads to complete. Example use Ø new->next = list_element->next; Ø wmb(); Ø list_element->next = new; 11

Spin Locks CPU “spins, ” executing instructions waiting for lock to free. Ø Only

Spin Locks CPU “spins, ” executing instructions waiting for lock to free. Ø Only useful on multi-processors Ø Insures only one kernel thread runs a routine at a time Value of 1 means lock is free spin_lock(spinlock_t slp) { 1: lock; decb slp jns 3 f 2: cmpb $0, slp pause // p 4 -reduces power jle 2 b // back compat rep; nop jmp 1 b 3: 12

R/W Spin Locks – space optimized data structure Many locks in kernel, so they

R/W Spin Locks – space optimized data structure Many locks in kernel, so they should be small. Ø Interpret bit ranges. Unlocked flag 2’s complement reader count 24 b 23 b 0 b 0 x 01000000 – Idle, not locked and no readers 0 x 0000 – Aquired for writing, no readers 0 x 00 FFFFFE – Aquired by 2 readers read_lock() = lock; subl $1, (rwlp)n jns 1 f read_unlock() = lock; incl rwlp rw_lock() = lock; subl %0 x 01000000, (rwlp)n jz 1 f rw_unlock() = lock; addl $0 x 01000000, rwlp 13

Semaphores Kernel semaphores suspend a waiting process, so can’t be called from interrupt handlers

Semaphores Kernel semaphores suspend a waiting process, so can’t be called from interrupt handlers and deferrable functions. Ø atomic_t count; // 1=available 0=busy -1=one waiting Ø wait_queue; // wait queue list Ø int sleepers; //flag, 1 if sleepers, optimization down() – acquire up() – release down_interruptable() Ø Used by device drivers. Suspend me, but if I get a signal, take me off the wait queue & return error. Read/write semaphores. Allows multiple readers. Ø Queues waiters, so it is fair to writers. Semaphore implementation only locks when manipulating the sleep queue. 14

Linux Use of Semaphores Linux uses semaphores in which processing path (primarily)? Ø Ø

Linux Use of Semaphores Linux uses semaphores in which processing path (primarily)? Ø Ø Ø A. Interrupt Handlers B. System call service routines C. Deferrable kernel functions D. Device drivers E. Kernel threads 15

Completions Solving race condition with temporary Semaphores Thread A, CPU 0 Alloc semaphore S

Completions Solving race condition with temporary Semaphores Thread A, CPU 0 Alloc semaphore S Pass sema to B down(S) free(S) Thread B, CPU 1 Accept sema S up(S) and free(S) execute concurrently. Ø lock only protects sleep queue, not whole semaphore Lock protects entire Completion. Ø Slower, but safer. 16

Local Interrupt Disable local_irq_disable()/local_irq_enable() Ø Disables and reenables interrupts Ø Executes cli/sti on x

Local Interrupt Disable local_irq_disable()/local_irq_enable() Ø Disables and reenables interrupts Ø Executes cli/sti on x 86 But interrupts can be nested, so what interrupt level to we return to? Ø Ø unsigned long flags; local_irq_disable(flags); …Read or update a data structure… local_irq_enable(flags); Disable clears the IF flag of the eflags register, and saves register in variable. Enable restores previous register value. 17

Uses of Synchronization in the Kernel Short Kernel Critical Sections Ø Disable interrupts (&

Uses of Synchronization in the Kernel Short Kernel Critical Sections Ø Disable interrupts (& grab spin lock on MPs) Long Critical Sections Interrupt Protection levels Ø Ø top-half interrupt handlers bottom-half interrupt handlers kernel-system service routines user-mode programs (preemptible) increasing priority Ø Separated into “top” and “bottom” Ø top - disable interrupts (& grab spin lock on MPs) Ø bottom – bottom halves don’t interrupt each other, so no sync needed on UP. On MP uses a lock to protect data structures from concurrent access. 18