Kernel synchronization - Washington University in St. Louis

advertisement
Kernel Synchronization
David Ferry, Chris Gill
CSE 522S - Advanced Operating Systems
Washington University in St. Louis
St. Louis, MO 63143
1
Linux is a Preemptive Kernel
The Linux kernel executes concurrently with
itself:
• Multiple processors (CONFIG_SMP)
• Interrupts
• Kernel Threads
Many data structures can be accessed
concurrently from different contexts, which
may cause concurrency bugs.
CSE 522S – Advanced Operating Systems
2
Single Variable Race Condition
Suppose two concurrent processes are accessing a
variable X with initial value of 1, what is the final
value of X?:
Thread 1:
load X
Thread 2:
load X
X = X + 1
X = X + 1
store X
store X
CSE 522S – Advanced Operating Systems
3
Data Structure Race Condition
Suppose two threads are accessing a list:
Node A Next
Node B Next
Deleter:
Node* = A->Next
A->Next = B->Next
Kfree(Node);
Node C Next
Reader:
Node* = A->Next
Value = Node->val
CSE 522S – Advanced Operating Systems
4
Shared Data Synchronization
Accessing shared data requires appropriate
synchronization
Protect data, not code!
A region of code that accesses shared data
is called a critical section
CSE 522S – Advanced Operating Systems
5
Basic Kernel Synchronization
The Linux kernel supports most of the same
synchronization primitives as userspace.
1.
2.
3.
4.
5.
Atomic variables
Spin locks (non-sleepable locks)
Mutexes (sleepable locks)
Reader-writer locks
Semaphores
CSE 522S – Advanced Operating Systems
6
Locking Example
Node A Next
Node B Next
Deleter:
lock( list_lock );
Node* = A->Next;
A->Next = B->Next;
Kfree(Node);
Unlock(list_lock);
Node C Next
Reader:
lock( list_lock );
Node* = A->Next;
Value = Node->val;
unlock( list_lock );
CSE 522S – Advanced Operating Systems
7
When to Use Different Types of Locks
Spin locks - very short lock durations and/or
very low overhead requirements
Mutexes - Long lock duration and/or process
needs to sleep while holding lock
Atomics - When shared data fits inside a
single word of memory
Other locks - special cases
CSE 522S – Advanced Operating Systems
8
Sleeping With Locks
Sleeping with a lock is generally a bad idea
unless absolutely necessary
• Delays other processes
• Deadlock risk: is it guaranteed to
eventually wake up and release the lock?
A process cannot sleep holding a spinlock.
• Restructure code to back out of lock
• Use a mutex instead
CSE 522S – Advanced Operating Systems
9
Deadlock
Deadlock occurs when a process can never
progress while waiting for a lock, e.g.:
Thread 1:
lock( A );
lock( B );
//critical section
unlock( A );
unlock( B );
Lock A
Lock B
Thread 2:
lock( B );
lock( A );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
10
Deadlock
Deadlock occurs when a process can never
progress while waiting for a lock, e.g.:
Thread 1:
lock( A );
lock( B );
//critical section
unlock( A );
unlock( B );
Lock A
Lock B
Thread 2:
lock( B );
lock( A );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
11
Deadlock
Deadlock occurs when a process can never
progress while waiting for a lock, e.g.:
Thread 1:
lock( A );
lock( B );
//critical section
unlock( A );
unlock( B );
Lock A
Lock B
Thread 2:
lock( B );
lock( A );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
12
Deadlock
Deadlock occurs when a process can never
progress while waiting for a lock, e.g.:
Thread 1:
lock( A );
lock( B );
//critical section
unlock( A );
unlock( B );
Lock A
Deadlock!
Lock B
Thread 2:
lock( B );
lock( A );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
13
Lock Ordering
Always acquire and release locks in the
same order! (Does not solve all deadlocks,
but it’s a good place to start.)
Thread 1:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
Lock A
Lock B
Thread 2:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
14
Lock Ordering
Always acquire and release locks in the
same order! (Does not solve all deadlocks,
but it’s a good place to start.)
Thread 1:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
Lock A
Lock B
Thread 2:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
15
Lock Ordering
Always acquire and release locks in the
same order! (Does not solve all deadlocks,
but it’s a good place to start.)
Thread 1:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
Lock A
Lock B
Thread 2:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
16
Lock Ordering
Always acquire and release locks in the
same order! (Does not solve all deadlocks,
but it’s a good place to start.)
Thread 1:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
Lock A
Lock B
Thread 2:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
17
Lock Ordering
Always acquire and release locks in the
same order! (Does not solve all deadlocks,
but it’s a good place to start.)
Thread 1:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
Lock A
Lock B
Thread 2:
lock( A );
lock( B );
//critical section
unlock( B );
unlock( A );
CSE 522S – Advanced Operating Systems
18
The BKL is No Longer Used
The Big Kernel Lock (BKL) was the first lock
introduced to the kernel
• Locks the entire kernel
• Provides correctness, but very slow
• New uses are prohibited
• Gradually replaced with finer-grained
locking schemes
CSE 522S – Advanced Operating Systems
19
Download