Sophie

Sophie

distrib > CentOS > 6 > i386 > by-pkgid > cf93d8a8acdcc6fe2225039da0502495 > files > 2221

kernel-doc-2.6.32-131.17.1.el6.centos.plus.noarch.rpm

<?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>Accessing From Interrupt Context</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="ch07.html" title="Chapter&#160;7.&#160;Common Examples" /><link rel="prev" href="ch07.html" title="Chapter&#160;7.&#160;Common Examples" /><link rel="next" href="ch07s03.html" title="Exposing Objects Outside This File" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Accessing From Interrupt Context</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch07.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;7.&#160;Common Examples</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch07s03.html">Next</a></td></tr></table><hr /></div><div class="sect1" title="Accessing From Interrupt Context"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="examples-interrupt"></a>Accessing From Interrupt Context</h2></div></div></div><p>
Now consider the case where <code class="function">cache_find</code> can be
called from interrupt context: either a hardware interrupt or a
softirq.  An example would be a timer which deletes object from the
cache.
    </p><p>
The change is shown below, in standard patch format: the
<span class="symbol">-</span> are lines which are taken away, and the
<span class="symbol">+</span> are lines which are added.
    </p><pre class="programlisting">
--- cache.c.usercontext	2003-12-09 13:58:54.000000000 +1100
+++ cache.c.interrupt	2003-12-09 14:07:49.000000000 +1100
@@ -12,7 +12,7 @@
         int popularity;
 };

-static DEFINE_MUTEX(cache_lock);
+static DEFINE_SPINLOCK(cache_lock);
 static LIST_HEAD(cache);
 static unsigned int cache_num = 0;
 #define MAX_CACHE_SIZE 10
@@ -55,6 +55,7 @@
 int cache_add(int id, const char *name)
 {
         struct object *obj;
+        unsigned long flags;

         if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
                 return -ENOMEM;
@@ -63,30 +64,33 @@
         obj-&gt;id = id;
         obj-&gt;popularity = 0;

-        mutex_lock(&amp;cache_lock);
+        spin_lock_irqsave(&amp;cache_lock, flags);
         __cache_add(obj);
-        mutex_unlock(&amp;cache_lock);
+        spin_unlock_irqrestore(&amp;cache_lock, flags);
         return 0;
 }

 void cache_delete(int id)
 {
-        mutex_lock(&amp;cache_lock);
+        unsigned long flags;
+
+        spin_lock_irqsave(&amp;cache_lock, flags);
         __cache_delete(__cache_find(id));
-        mutex_unlock(&amp;cache_lock);
+        spin_unlock_irqrestore(&amp;cache_lock, flags);
 }

 int cache_find(int id, char *name)
 {
         struct object *obj;
         int ret = -ENOENT;
+        unsigned long flags;

-        mutex_lock(&amp;cache_lock);
+        spin_lock_irqsave(&amp;cache_lock, flags);
         obj = __cache_find(id);
         if (obj) {
                 ret = 0;
                 strcpy(name, obj-&gt;name);
         }
-        mutex_unlock(&amp;cache_lock);
+        spin_unlock_irqrestore(&amp;cache_lock, flags);
         return ret;
 }
</pre><p>
Note that the <code class="function">spin_lock_irqsave</code> will turn off
interrupts if they are on, otherwise does nothing (if we are already
in an interrupt handler), hence these functions are safe to call from
any context.
    </p><p>
Unfortunately, <code class="function">cache_add</code> calls
<code class="function">kmalloc</code> with the <span class="symbol">GFP_KERNEL</span>
flag, which is only legal in user context.  I have assumed that
<code class="function">cache_add</code> is still only called in user context,
otherwise this should become a parameter to
<code class="function">cache_add</code>.
    </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ch07.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="ch07.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="ch07s03.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&#160;7.&#160;Common Examples&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Exposing Objects Outside This File</td></tr></table></div></body></html>