<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968" /><title>Chapter 8. Common Problems</title><meta name="generator" content="DocBook XSL Stylesheets V1.75.2" /><link rel="home" href="index.html" title="Unreliable Guide To Locking" /><link rel="up" href="index.html" title="Unreliable Guide To Locking" /><link rel="prev" href="ch07s04.html" title="Protecting The Objects Themselves" /><link rel="next" href="ch08s02.html" title="Preventing Deadlock" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 8. Common Problems</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07s04.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="ch08s02.html">Next</a></td></tr></table><hr /></div><div class="chapter" title="Chapter 8. Common Problems"><div class="titlepage"><div><div><h2 class="title"><a id="common-problems"></a>Chapter 8. Common Problems</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="ch08.html#deadlock">Deadlock: Simple and Advanced</a></span></dt><dt><span class="sect1"><a href="ch08s02.html">Preventing Deadlock</a></span></dt><dd><dl><dt><span class="sect2"><a href="ch08s02.html#techs-deadlock-overprevent">Overzealous Prevention Of Deadlocks</a></span></dt></dl></dd><dt><span class="sect1"><a href="ch08s03.html">Racing Timers: A Kernel Pastime</a></span></dt></dl></div><div class="sect1" title="Deadlock: Simple and Advanced"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="deadlock"></a>Deadlock: Simple and Advanced</h2></div></div></div><p> There is a coding bug where a piece of code tries to grab a spinlock twice: it will spin forever, waiting for the lock to be released (spinlocks, rwlocks and mutexes are not recursive in Linux). This is trivial to diagnose: not a stay-up-five-nights-talk-to-fluffy-code-bunnies kind of problem. </p><p> For a slightly more complex case, imagine you have a region shared by a softirq and user context. If you use a <code class="function">spin_lock()</code> call to protect it, it is possible that the user context will be interrupted by the softirq while it holds the lock, and the softirq will then spin forever trying to get the same lock. </p><p> Both of these are called deadlock, and as shown above, it can occur even with a single CPU (although not on UP compiles, since spinlocks vanish on kernel compiles with <span class="symbol">CONFIG_SMP</span>=n. You'll still get data corruption in the second example). </p><p> This complete lockup is easy to diagnose: on SMP boxes the watchdog timer or compiling with <span class="symbol">DEBUG_SPINLOCK</span> set (<code class="filename">include/linux/spinlock.h</code>) will show this up immediately when it happens. </p><p> A more complex problem is the so-called 'deadly embrace', involving two or more locks. Say you have a hash table: each entry in the table is a spinlock, and a chain of hashed objects. Inside a softirq handler, you sometimes want to alter an object from one place in the hash to another: you grab the spinlock of the old hash chain and the spinlock of the new hash chain, and delete the object from the old one, and insert it in the new one. </p><p> There are two problems here. First, if your code ever tries to move the object to the same chain, it will deadlock with itself as it tries to lock it twice. Secondly, if the same softirq on another CPU is trying to move another object in the reverse direction, the following could happen: </p><div class="table"><a id="id3051530"></a><p class="title"><b>Table 8.1. Consequences</b></p><div class="table-contents"><table summary="Consequences" border="1"><colgroup><col /><col /></colgroup><thead><tr><th align="left">CPU 1</th><th align="left">CPU 2</th></tr></thead><tbody><tr><td align="left">Grab lock A -> OK</td><td align="left">Grab lock B -> OK</td></tr><tr><td align="left">Grab lock B -> spin</td><td align="left">Grab lock A -> spin</td></tr></tbody></table></div></div><br class="table-break" /><p> The two CPUs will spin forever, waiting for the other to give up their lock. It will look, smell, and feel like a crash. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07s04.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="ch08s02.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Protecting The Objects Themselves </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Preventing Deadlock</td></tr></table></div></body></html>