What is so critical about *Critical Sections*

I have just started reading *Essential Device Driver* book by Sreekrishnan Venkateswaran.
One of things that really impressed me was the coverage of topic *Concurrency in Linux Kernel*, which even talks about *Preemption* and *Real Time* scenarios. Consider these four situations....

1. Critical section present only in process context on a Uniprocessor (UP) box running a non-preemptible
kernel.

This is straight forward situation, where one does not need to worry much about concurrency.

2. Critical section present in process and interrupt contexts on a UP machine running a non-preemptible
kernel.

In this case, Interrupts are of higher priority and than process(common sense)...mechanism required for concurrency ...very simple...

unsigned long flags;
local_irq_save(flags);
/* here goes your critical code......*/
local_irq_restore(flags);


3. Critical section present in process and interrupt contexts on a UP machine running a preemptible kernel.

This get interesting, just by disabling interrupts here wont solve concurrency issue. An example stated in the book is "multiple threads may enter the critical section simultaneously in the process context...." so concurrency can be achieved by,

spinlock_t my_lock;
spin_lock_init(&my_lock);
unsigned long flags;

spin_lock_irqsave(&my_lock, flags);
/* your critical section code ....*/
spin_unlock_irqrestore(&my_lock, flags);


Note: spin_lock_irqsave(), internally calls preempt_disable() and spin_unlock_irqrestore calls preempt_enable()......explicitly disabling/enabling preemption is not required!!!.(look at kernel/spinlock.c in the kernel souce).

4. Critical section present in process and interrupt contexts on an SMP machine running a preemptible kernel

This is the most complicated situation, where in protection of data structures in the kenrel needs to be handled with utmost care.

For this, you'll need your kernel compiled with CONFIG_SMP and CONFIG_PREEMPT.

From the book "....In the presence of SMP, the locking logic gets compiled in, and the spinlock primitives are rendered SMP-safe...."

Here's what you do,

unsigned long flags;
/*save interrupts on local CPU
disable interrupts on local CPU
lock the section to regulate access by other CPU's
*/
spin_lock_irqsave(&my_lock, flags);
/* critical section here */
spin_lock_irqrestore(&my_lock, flags);



This book is a wonderful read. I can't wait to explore other chapters.


About this entry


0 comments: