ch 8, 9 kernel synchronization

Post on 04-Feb-2016

29 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

제 45 강 : Kernel Synchronization. Ch 8, 9 Kernel Synchronization. How CPU performs X++. CPU. variable X is stored in storage box storage box can not compute computation is performed in CPU. (2). Register. Memory. (1). (3). load: CPU register  storage X - PowerPoint PPT Presentation

TRANSCRIPT

1

Ch 8, 9 Kernel Synchronization

제 45 강 : Kernel Synchronization

2

How CPU performs X++

(1)load: CPU register storage X (2)compute: register ++ (3) store: CPU register storage X

Memory

CPU

X

Register

variable X is stored in storage boxstorage box can not compute

computation is performed in CPU

(2)

(1) (3)

3

(Three Cases of Race)

A. 2 CPU’s sharing a variable

B. Kernel base code v.s. Interrupt

handler

C. Kernel Preemption between

Processes

4

(Case A)2 CPU’s sharing a variable

5

(Case) CPU’s not sharing variable

CPU #0

Shared Memory

vi a.out

sh a.out

kernel a.out

program counter

CPU #1 program counter

CPU #2 program counter

CPU #3 program counter

6

CPU #0

Shared Memory

vi a.out

sh a.out

kernel a.out

X

program counter

CPU #1 program counter

CPU #2 program counter

CPU #3 program counter

load X compu

testore X

load X compu

testore X

(Case A) SMP sharing variable

user

user

user

user

7

• Thread 1(access X)

load X (X=7)--------------increment X (7 8)--------------store back X (X=8)--------------

• Thread 2(access X)

--------------load X (X=7)--------------increment X (7 8)--------------store back X (X=8)

Thread 1(access X)

load X (X=7)increment X (78)store back X (X=8)------------------------------------------

Thread 2(access X)

------------------------------------------load X (X=8)increment X (89)store back X (X=9)

interleavedexecution

atomicexecution

(mutual exclusion)

---- Incorrect lost update!

---- Correct

8

Introduction• Critical region (critical section):

– Code path that reads & writes shared data

• Race condition :– two threads(tasks) simultaneously

executing the same kind of critical region. (interleaved execution)

• Synchronization :– make sure race condition does not occur– Guarantee atomic execution within critical

region (serialize accesses)

9

(Case B)

kernel base code v.s. interrupt

handler

10

CPU

load X compu

testore X

others

others

load X compu

testore X

others

others

Register

(1)(2)

(3)

(4)(5)

kernel base interrupt handler

(Case B) kernel base code v.s. interrupt

handler

R=10

X=10

R=11

R=10

R=11

X=11X=11

11

(Case C) Process Context Switch

during System Call Execution

12

load X compu

testore X

load X compu

testore X

KernelSystem

Call

KernelSystem

Call

user

user

user

user

Shared Memory

vi a.out

sh a.out

kernel a.out

X

CPU program counter

(Case C) Process Context Switch during System Call

Execution

(sh) (vi)

13

Linux functions for Preventing Race

1. Atomic functions• for simple operations

2. Spinlock• busy-wait

3. Semaphore• block_wakeup (1) load X

(2) compute (3) store X

explicit lock Sleep if fail

(1) load X (2) compute (3) store X

explicit lock Keep checkingif fail

(1) load X (2) compute (3) store X

simple operation like + ++ - * / atomic_inc(X)

14

(1) Atomic functions

• For simple operations• For Integer -- init, read, set, add, inc, …

eg atomic_set (&v, 4); //v=4 atomic_inc(&v); //v++

• For Boolean -- set, clear, change, testeg set_bit (0, &word); //set the bit zero of &word

change_bit (0, &word); //flip test_and_set_bit(0, &word) //set the bit zero &

return previous value//

• If CR is a simple (integer or boolean) operation,

then just use these atomic operations

15

Lock

• General structure of process Pi

• Each process:do {

entry section Lock (wait if in use)

critical region (CR)exit section Unlockremainder section

} while (1);

16

Lock - several issues

• What do you do while waiting for lock release?– busy-wait – block-&-wakeup

• Size of the area this lock protects (lock granularity) – Single lock -- entire kernel– Many locks -- one for each small critical region (variable)– concurrency vs overhead

• Deadlock – deadlock prevention, avoidance, detection– thread 1 thread 2

acquire lock A acquire lock Btry to acquire lock B try to acquire lock A

17

2 kinds of lock1. Spin lock

– busy-wait– lock memory-bus if necessary (Ch 9)– holding time should be short– should not sleep while holding it

2. Semaphore– block-&-wakeup– context switch overhead (sleep, wakeup)– you can sleep while holding this lock

CPU CPU

BUS

MEMORY

18

(2) Spin Lock• busy loop• Lock holding time should be short• spin locks can be used in interrupt handlers (in this case one should disable local

interrupts)• Cannot request spin lock you already hold (i.e. spin locks are not recursive in Linux)• spin lock can be dynamically created

spinlock_t my_lock = SPIN_LOCK_UNLOCKED; // declarationspin_lock(&my_lock); --- critical region ---spin_unlock(&my_lock);

19

(3) Semaphores• Sleeping lock• Failed to obtain the semaphore? go to sleep

– Interrupt handler cannot use it (IH cannot sleep)– hold both spinlock & semaphore? Don’t try

• When do we use – When (lock holding time) > overhead

(sleep+wakeup)– only in process context (not in interrupt hander)

• Semaphores do not disable kernel preemption.

down (&sem); // P(), sleep if fail (not respond to signal)up (&sem); // V(), release the given semaphore

20

Which method to use : Spin lock vs. Semaphore

• Requirements

low overhead lockingshort lock hold timeinterrupt contextneed to sleep

• Recommended Lock

spin lock is preferredspin lock is preferredspin lock is requiredsemaphore is required

21

A. Symmetrical multiprocessing (Multiple CPU’s)2 CPU’s – each enter the same type of CR’s (fetch x, add, store x)Cure: use semaphore when enter/exiting CR (“SMP-safe”)

Other CPU is not allowed to enter same type of CR

B. Interrupt (Single CPU) kernel is in the middle of CR (fetch x, add, store x) interruptinterrupt handler enters the same CR (fetch x, add, store x)Cure: disable interrupt while kernel enters CR (“interrupt-safe”) Interrupt cannot occur in this CR

C. Kernel preemption (Single CPU) /* Linux now allows kernel preemption Do this safely */

kernel is in the middle of CR A (fetch x, add, store x) preempt CPUCPU Other task X. invokes system call (enter kernel)kernel enters the same CR A (fetch x, add, store x)Cure: Not allow preemption during kernel CR (“preempt-safe”) kernel is guaranteed to complete this CRPA

PX

CR(x)

CR(x)

Kernel Base Code

CR(x)

Interrupt Handler

CR(x)

cpu cpu

CR(x)

disableintrp

Lock(x)

disablepreemption

Where -- race conditions

22

Advanced Issues

23

Reader-Writer Spin Lock

• reader lock -- allow many readers to share lock• writer lock -- at most one writer (no readers)• use when code is clearly separated -- R/W section.• Favors readers over writers writer waits until all readers have finished

rwlock_t mr_rwlock; read_lock(&mr_rwlock) write_lock(&mr_rwlock)read_unlock(&mr_rwlock) write_unlock(&mr_rwlock)

24

Seq Locks• Write Lock

– “No other writers?” ---- always succeed– initial value of this lock is zero– when acquiring lock, seqeunce_counter++

becomes odd

– when releasing lock, seqeunce_counter++ becomes even

– “odd” means “writer is currently working” • Reader

– goal -- obtain the most recent version– before READ -- copy sequence_counter to local variable – after READ ---- get current sequence_counter,

• If recent value is odd retry READ• If (current value <> saved value) retry READ

• Favors writer over reader – writer does not wait for reader

• scalable -- many readers and only a few writers

c R

i

but diffvalue?

retry

even

evenW

W

25

Comparison1. Spin-lock

– do not allow concurrent access to shared data– busy-wait

2. Semaphore– do not allow concurrent access to shared data– block & wakeup

3. Reader/Writer spin-lockreader has higher priority over writer

– allow multiple readers to access shared data concurrently4. Seqlock

– writer has higher priority over reader– allow multiple readers to access shared data concurrently

26

BKL : The Big Kernel Lock

• 1st SMP implementation• Global spin lock• Only one task could be in kernel at a time• Later, fine-grained locking was introduced multiple CPU’s execute kernel

concurrently• BKL is not scalable• BKL is obsolete now.

lock_kernel();unlock_kernel();

27

Completion Variables

• PA needs to signal PB that an event has occurred.

PB : wait_for_completion (struct completion *);

//waits for the completion variable to be signaled sleep

PA : complete (struct completion *);

// signals any tasks waiting at completion var. wake up

Init: init_completion (struct completion *);//initialization

28

Barriers• Both the compiler and the processor can reorder

reads and writes for performance reason.• ordering (read & write) is important for locking• Barriers

– “no read/write reordering allowed across barriers”.

rmb() : load(read) barrierwmb() : store(write) barriermb() : load & store barrier

29

thread 1 a=3; b=4;--

thread 2--c = b; d = a;

thread 1a=3; mb();b=4;--

thread 2--c = b;rmb();d = a;

Initally a = 1, b = 2

// c=4, d=1 can happen

// c=4, d=1 can not happen

30

Ch 10 Timers and Time Management

31

Terminology• HZ

– tick rate (differs for each architecture) #define HZ 1000

(include/asm-i386/param.h)– In most other architecture, HZ is 100– i386 architecture (since 2.5 series)

• jiffies– number of ticks since system boot – global variable

• jiffies-Hz-Time– To convert from [seconds to jiffies]

• (second * HZ)– To convert from [jiffies to seconds]

• (jiffies / HZ)

tickticktick

1000 Hz

100 Hz

Jiffies

32

Terminology

• Issues on HZ – If increase the tick rate from 100 Hz 1000

Hz?•All timed events have a higher resolution •and the accuracy of timed events improve•overhead of timer Interrupt increase .

• Issues on jiffies– Internal representation of jiffies– jiffies wrap-around

33

Hardware Clocks and Timers

• System Timer– Drive an interrupt at a periodic rate– Programmable Interrupt Timer (PIT) on X86– kernel programs PIT on boot to drive timer interrupt

at HZ

• Real-Time Clock (RTC)– Nonvolatile device for storing the time– RTC continues even when the system is off (small

battery)– On boot, kernel reads the RTC – Initialize the wall time (in struct timespec xtime)

34

Timer Interrupt Handler• The architecture-dependent routine

– Acknowledge or reset system timer as required– Periodically save the updated wall time to the RTC– Call the architecture-independent timer routine,

do_timer()

• The architecture-independent routine– jiffies++ – Update the wall time– Update resource usages– Run any dynamic timers that have expired– Calculate load average

35

Timer Interrupt Handlervoid do_timer(struct pt_regs *regs){ jiffies_64++; /* increment jiffies */ update_process_times(user_mode(regs)); update_times();}

void update_process_times(int user_tick){ struct task_struct *p = current; int cpu = smp_processor_id(), system = user_tick ^ 1; update_one_process(p, user_tick, system, cpu); run_local_timers(); /* marks a softirq */ scheduler_tick(user_tick, system);

/* decrements the currently running process’s timeslice and sets need_resched if needed */

}

static inline void update_times(void){ unsigned long ticks; ticks = jiffies - wall_jiffies; if (ticks) { wall_jiffies += ticks; update_wall_time(ticks); } calc_load(ticks);}

1 if user mode0 if kernel mode

p->utime += user;p->stime += system;

36

The Time of Day• The wall time

– xtime.tv_sec value stores the number of seconds that have elapsed since January 1, 1970 (epoch)

– xtime.tv_nsec value stores the number of nanosecnds that have elapsed in the last second

struct timespec xtime;strut timespec {

time_t tv_sec; /* seconds */long tv_nsec; /* nanoseconds */

};

37

Timers• Timers --- eg “run fA() every 250 ms.”

– Kernel code often needs to delay execution of some function until a later time

– e.g.) bottom half mechanisms

• How to use timers – Initial setup

• Specify expiration time• Specify function to execute upon said expiration

– Activate the timer

38

Timers

• Timer structure

struct timer_list {

struct list_head entry; /* timers are part of linked list */

unsigned long expires; /* expiration value, in jiffies */

spinlock_t lock; /* lock protecting this timer */

void (*function)(unsigned long); /* the timer handler function */

unsigned long data; /* lone argument to the handler */

};

39

Timers

• Using Timers– Define timer

– Initialize the timer’s internal values

– Fill out the remaining values as required

– Activate the timer

struct timer_list my_timer;

init_timer(&my_timer);

my_timer.expires = jiffies + delay; /* timer expires in delay ticks */my_timer.data = 0; /* zero is passed to timer handler */my_timer.function = my_function; /* function to run when timer expires */

add_timer(&my_timer);

40

Delaying Execution• Schedule_timeout()

set_current_state (TASK_INTERRUPTIBLE); /* put the task to sleep */schedule_timeout (s * HZ);

signed long schedule_timeout(signed long timeout){

struct timer_list timer; /* create timer */unsigned long expire;expire = timeout + jiffies;init_timer(&timer); /* initialize the timer */timer.expires = expire;timer.data = (unsigned long) current;timer.function = process_timeout;add_timer(&timer); /* activate the timer */schedule(); /* call schedule() */del_timer_sync(&timer);timeout = expire - jiffies;return timeout < 0 ? 0 : timeout;

}

static void process_timeout(unsigned long __data){ wake_up_process((task_t *)__data);}

41

Other Ways to Delay Execution

• Busy Looping (as soon as …)unsigned long delay = jiffies + 10; /* ten ticks

*/while (time_before(jiffies, delay));

• Small Delays (micro-, or milli- seconds)void udelay(unsigned long usecs);void mdelay(unsigned long msecs);udelay(150); /* delay for 150 us

top related