Project

General

Profile

Feature #5349

Updated by Vadim Mutilin about 10 years ago

*Summary* 

 # It’s not allowed to acquire spin_lock twice.  
 # It’s not allowed to release not acquired spin_lock.  
 # At the end all spin_lock should be released.  

 *Description* 

 Unlike other operating systems spin-locks in Linux are not recursive. So if a thread tries to acquire a lock it has already acquired then this thread begins a periodical check and waits till it releases the lock. This leads to a deadlocks. The situation is not often in its explicit form, but it is widely spread in an implicit form when some function (external function usually) tries to acquire a lock that has already been acquired by the module. 

 It’s not allowed to acquire spin_lock twice. It’s not allowed to release not acquired spin_lock. At the end all spin_lock should be released. It’s not allowed to re-release a lock by spin_unlock/spin_unlock_irqrestore functions. 

 *Links* 

 Sample bugfixes "82eabdf":https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=82eabdf, "83c7c693":https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=83c7c693ed3e61535ad6a097ad991a88aafc54b8 "Sample bugfix":https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=83c7c693ed3e61535ad6a097ad991a88aafc54b8 

 *Example* 

 example of bug (2.6.24 -> 2.6.25, drivers/char/specialix.c): 

 <pre><code class="с"> 
     @@ 2109   
     sx_out(bp, CD186x_CAR, port_No(port));   
     /* releasing a lock */   
     spin_unlock_irqrestore(&bp->lock, flags);    
     if (I_IXOFF(tty)) {   
         /* in some cases double unlock is possible */   
         spin_unlock_irqrestore(&bp->lock, flags);   
         sx_wait_CCR(bp);   
         spin_lock_irqsave(&bp->lock, flags);   
         sx_out(bp, CD186x_CCR, CCR_SSCH2);  
 </code></pre>

Back