1<html><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.78.1"><link rel="home" href="index.html" title="Unreliable Guide To Locking"><link rel="up" href="Examples.html" title="Chapter&#160;7.&#160;Common Examples"><link rel="prev" href="Examples.html" title="Chapter&#160;7.&#160;Common Examples"><link rel="next" href="examples-refcnt.html" title="Exposing Objects Outside This File"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><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="Examples.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="examples-refcnt.html">Next</a></td></tr></table><hr></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="examples-interrupt"></a>Accessing From Interrupt Context</h2></div></div></div><p>
2Now consider the case where <code class="function">cache_find</code> can be
3called from interrupt context: either a hardware interrupt or a
4softirq.  An example would be a timer which deletes object from the
5cache.
6    </p><p>
7The change is shown below, in standard patch format: the
8<span class="symbol">-</span> are lines which are taken away, and the
9<span class="symbol">+</span> are lines which are added.
10    </p><pre class="programlisting">
11--- cache.c.usercontext	2003-12-09 13:58:54.000000000 +1100
12+++ cache.c.interrupt	2003-12-09 14:07:49.000000000 +1100
13@@ -12,7 +12,7 @@
14         int popularity;
15 };
16
17-static DEFINE_MUTEX(cache_lock);
18+static DEFINE_SPINLOCK(cache_lock);
19 static LIST_HEAD(cache);
20 static unsigned int cache_num = 0;
21 #define MAX_CACHE_SIZE 10
22@@ -55,6 +55,7 @@
23 int cache_add(int id, const char *name)
24 {
25         struct object *obj;
26+        unsigned long flags;
27
28         if ((obj = kmalloc(sizeof(*obj), GFP_KERNEL)) == NULL)
29                 return -ENOMEM;
30@@ -63,30 +64,33 @@
31         obj-&gt;id = id;
32         obj-&gt;popularity = 0;
33
34-        mutex_lock(&amp;cache_lock);
35+        spin_lock_irqsave(&amp;cache_lock, flags);
36         __cache_add(obj);
37-        mutex_unlock(&amp;cache_lock);
38+        spin_unlock_irqrestore(&amp;cache_lock, flags);
39         return 0;
40 }
41
42 void cache_delete(int id)
43 {
44-        mutex_lock(&amp;cache_lock);
45+        unsigned long flags;
46+
47+        spin_lock_irqsave(&amp;cache_lock, flags);
48         __cache_delete(__cache_find(id));
49-        mutex_unlock(&amp;cache_lock);
50+        spin_unlock_irqrestore(&amp;cache_lock, flags);
51 }
52
53 int cache_find(int id, char *name)
54 {
55         struct object *obj;
56         int ret = -ENOENT;
57+        unsigned long flags;
58
59-        mutex_lock(&amp;cache_lock);
60+        spin_lock_irqsave(&amp;cache_lock, flags);
61         obj = __cache_find(id);
62         if (obj) {
63                 ret = 0;
64                 strcpy(name, obj-&gt;name);
65         }
66-        mutex_unlock(&amp;cache_lock);
67+        spin_unlock_irqrestore(&amp;cache_lock, flags);
68         return ret;
69 }
70</pre><p>
71Note that the <code class="function">spin_lock_irqsave</code> will turn off
72interrupts if they are on, otherwise does nothing (if we are already
73in an interrupt handler), hence these functions are safe to call from
74any context.
75    </p><p>
76Unfortunately, <code class="function">cache_add</code> calls
77<code class="function">kmalloc</code> with the <span class="symbol">GFP_KERNEL</span>
78flag, which is only legal in user context.  I have assumed that
79<code class="function">cache_add</code> is still only called in user context,
80otherwise this should become a parameter to
81<code class="function">cache_add</code>.
82    </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="Examples.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="Examples.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="examples-refcnt.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>
83