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 7. Common Examples"><link rel="prev" href="Examples.html" title="Chapter 7. 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> </td><th width="60%" align="center">Chapter 7. Common Examples</th><td width="20%" align="right"> <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->id = id; 32 obj->popularity = 0; 33 34- mutex_lock(&cache_lock); 35+ spin_lock_irqsave(&cache_lock, flags); 36 __cache_add(obj); 37- mutex_unlock(&cache_lock); 38+ spin_unlock_irqrestore(&cache_lock, flags); 39 return 0; 40 } 41 42 void cache_delete(int id) 43 { 44- mutex_lock(&cache_lock); 45+ unsigned long flags; 46+ 47+ spin_lock_irqsave(&cache_lock, flags); 48 __cache_delete(__cache_find(id)); 49- mutex_unlock(&cache_lock); 50+ spin_unlock_irqrestore(&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(&cache_lock); 60+ spin_lock_irqsave(&cache_lock, flags); 61 obj = __cache_find(id); 62 if (obj) { 63 ret = 0; 64 strcpy(name, obj->name); 65 } 66- mutex_unlock(&cache_lock); 67+ spin_unlock_irqrestore(&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> </td><td width="20%" align="center"><a accesskey="u" href="Examples.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="examples-refcnt.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 7. Common Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Exposing Objects Outside This File</td></tr></table></div></body></html> 83