aboutsummaryrefslogtreecommitdiff
path: root/Documentation/DocBook
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/DocBook')
-rw-r--r--Documentation/DocBook/kernel-locking.tmpl57
-rw-r--r--Documentation/DocBook/uio-howto.tmpl63
2 files changed, 75 insertions, 45 deletions
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl
index 2510763295d..084f6ad7b7a 100644
--- a/Documentation/DocBook/kernel-locking.tmpl
+++ b/Documentation/DocBook/kernel-locking.tmpl
@@ -219,10 +219,10 @@
</para>
<sect1 id="lock-intro">
- <title>Three Main Types of Kernel Locks: Spinlocks, Mutexes and Semaphores</title>
+ <title>Two Main Types of Kernel Locks: Spinlocks and Mutexes</title>
<para>
- There are three main types of kernel locks. The fundamental type
+ There are two main types of kernel locks. The fundamental type
is the spinlock
(<filename class="headerfile">include/asm/spinlock.h</filename>),
which is a very simple single-holder lock: if you can't get the
@@ -240,14 +240,6 @@
use a spinlock instead.
</para>
<para>
- The third type is a semaphore
- (<filename class="headerfile">include/linux/semaphore.h</filename>): it
- can have more than one holder at any time (the number decided at
- initialization time), although it is most commonly used as a
- single-holder lock (a mutex). If you can't get a semaphore, your
- task will be suspended and later on woken up - just like for mutexes.
- </para>
- <para>
Neither type of lock is recursive: see
<xref linkend="deadlock"/>.
</para>
@@ -278,7 +270,7 @@
</para>
<para>
- Semaphores still exist, because they are required for
+ Mutexes still exist, because they are required for
synchronization between <firstterm linkend="gloss-usercontext">user
contexts</firstterm>, as we will see below.
</para>
@@ -289,18 +281,17 @@
<para>
If you have a data structure which is only ever accessed from
- user context, then you can use a simple semaphore
- (<filename>linux/linux/semaphore.h</filename>) to protect it. This
- is the most trivial case: you initialize the semaphore to the number
- of resources available (usually 1), and call
- <function>down_interruptible()</function> to grab the semaphore, and
- <function>up()</function> to release it. There is also a
- <function>down()</function>, which should be avoided, because it
+ user context, then you can use a simple mutex
+ (<filename>include/linux/mutex.h</filename>) to protect it. This
+ is the most trivial case: you initialize the mutex. Then you can
+ call <function>mutex_lock_interruptible()</function> to grab the mutex,
+ and <function>mutex_unlock()</function> to release it. There is also a
+ <function>mutex_lock()</function>, which should be avoided, because it
will not return if a signal is received.
</para>
<para>
- Example: <filename>linux/net/core/netfilter.c</filename> allows
+ Example: <filename>net/netfilter/nf_sockopt.c</filename> allows
registration of new <function>setsockopt()</function> and
<function>getsockopt()</function> calls, with
<function>nf_register_sockopt()</function>. Registration and
@@ -515,7 +506,7 @@
<listitem>
<para>
If you are in a process context (any syscall) and want to
- lock other process out, use a semaphore. You can take a semaphore
+ lock other process out, use a mutex. You can take a mutex
and sleep (<function>copy_from_user*(</function> or
<function>kmalloc(x,GFP_KERNEL)</function>).
</para>
@@ -662,7 +653,7 @@
<entry>SLBH</entry>
<entry>SLBH</entry>
<entry>SLBH</entry>
-<entry>DI</entry>
+<entry>MLI</entry>
<entry>None</entry>
</row>
@@ -692,8 +683,8 @@
<entry>spin_lock_bh</entry>
</row>
<row>
-<entry>DI</entry>
-<entry>down_interruptible</entry>
+<entry>MLI</entry>
+<entry>mutex_lock_interruptible</entry>
</row>
</tbody>
@@ -1310,7 +1301,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>.
<para>
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 semaphores are not
+ 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.
@@ -1335,7 +1326,7 @@ as Alan Cox says, <quote>Lock data, not code</quote>.
<para>
This complete lockup is easy to diagnose: on SMP boxes the
- watchdog timer or compiling with <symbol>DEBUG_SPINLOCKS</symbol> set
+ watchdog timer or compiling with <symbol>DEBUG_SPINLOCK</symbol> set
(<filename>include/linux/spinlock.h</filename>) will show this up
immediately when it happens.
</para>
@@ -1558,7 +1549,7 @@ the amount of locking which needs to be done.
<title>Read/Write Lock Variants</title>
<para>
- Both spinlocks and semaphores have read/write variants:
+ Both spinlocks and mutexes have read/write variants:
<type>rwlock_t</type> and <structname>struct rw_semaphore</structname>.
These divide users into two classes: the readers and the writers. If
you are only reading the data, you can get a read lock, but to write to
@@ -1681,7 +1672,7 @@ the amount of locking which needs to be done.
#include &lt;linux/slab.h&gt;
#include &lt;linux/string.h&gt;
+#include &lt;linux/rcupdate.h&gt;
- #include &lt;linux/semaphore.h&gt;
+ #include &lt;linux/mutex.h&gt;
#include &lt;asm/errno.h&gt;
struct object
@@ -1913,7 +1904,7 @@ machines due to caching.
</listitem>
<listitem>
<para>
- <function> put_user()</function>
+ <function>put_user()</function>
</para>
</listitem>
</itemizedlist>
@@ -1927,13 +1918,13 @@ machines due to caching.
<listitem>
<para>
- <function>down_interruptible()</function> and
- <function>down()</function>
+ <function>mutex_lock_interruptible()</function> and
+ <function>mutex_lock()</function>
</para>
<para>
- There is a <function>down_trylock()</function> which can be
+ There is a <function>mutex_trylock()</function> which can be
used inside interrupt context, as it will not sleep.
- <function>up()</function> will also never sleep.
+ <function>mutex_unlock()</function> will also never sleep.
</para>
</listitem>
</itemizedlist>
@@ -2023,7 +2014,7 @@ machines due to caching.
<para>
Prior to 2.5, or when <symbol>CONFIG_PREEMPT</symbol> is
unset, processes in user context inside the kernel would not
- preempt each other (ie. you had that CPU until you have it up,
+ preempt each other (ie. you had that CPU until you gave it up,
except for interrupts). With the addition of
<symbol>CONFIG_PREEMPT</symbol> in 2.5.4, this changed: when
in user context, higher priority tasks can "cut in": spinlocks
diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
index fdd7f4f887b..df87d1b9360 100644
--- a/Documentation/DocBook/uio-howto.tmpl
+++ b/Documentation/DocBook/uio-howto.tmpl
@@ -21,6 +21,18 @@
</affiliation>
</author>
+<copyright>
+ <year>2006-2008</year>
+ <holder>Hans-Jürgen Koch.</holder>
+</copyright>
+
+<legalnotice>
+<para>
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+</para>
+</legalnotice>
+
<pubdate>2006-12-11</pubdate>
<abstract>
@@ -30,6 +42,12 @@
<revhistory>
<revision>
+ <revnumber>0.5</revnumber>
+ <date>2008-05-22</date>
+ <authorinitials>hjk</authorinitials>
+ <revremark>Added description of write() function.</revremark>
+ </revision>
+ <revision>
<revnumber>0.4</revnumber>
<date>2007-11-26</date>
<authorinitials>hjk</authorinitials>
@@ -57,20 +75,9 @@
</bookinfo>
<chapter id="aboutthisdoc">
-<?dbhtml filename="about.html"?>
+<?dbhtml filename="aboutthis.html"?>
<title>About this document</title>
-<sect1 id="copyright">
-<?dbhtml filename="copyright.html"?>
-<title>Copyright and License</title>
-<para>
- Copyright (c) 2006 by Hans-Jürgen Koch.</para>
-<para>
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-</para>
-</sect1>
-
<sect1 id="translations">
<?dbhtml filename="translations.html"?>
<title>Translations</title>
@@ -189,6 +196,30 @@ interested in translating it, please email me
represents the total interrupt count. You can use this number
to figure out if you missed some interrupts.
</para>
+ <para>
+ For some hardware that has more than one interrupt source internally,
+ but not separate IRQ mask and status registers, there might be
+ situations where userspace cannot determine what the interrupt source
+ was if the kernel handler disables them by writing to the chip's IRQ
+ register. In such a case, the kernel has to disable the IRQ completely
+ to leave the chip's register untouched. Now the userspace part can
+ determine the cause of the interrupt, but it cannot re-enable
+ interrupts. Another cornercase is chips where re-enabling interrupts
+ is a read-modify-write operation to a combined IRQ status/acknowledge
+ register. This would be racy if a new interrupt occurred
+ simultaneously.
+ </para>
+ <para>
+ To address these problems, UIO also implements a write() function. It
+ is normally not used and can be ignored for hardware that has only a
+ single interrupt source or has separate IRQ mask and status registers.
+ If you need it, however, a write to <filename>/dev/uioX</filename>
+ will call the <function>irqcontrol()</function> function implemented
+ by the driver. You have to write a 32-bit value that is usually either
+ 0 or 1 to disable or enable interrupts. If a driver does not implement
+ <function>irqcontrol()</function>, <function>write()</function> will
+ return with <varname>-ENOSYS</varname>.
+ </para>
<para>
To handle interrupts properly, your custom kernel module can
@@ -362,6 +393,14 @@ device is actually used.
<function>open()</function>, you will probably also want a custom
<function>release()</function> function.
</para></listitem>
+
+<listitem><para>
+<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
+</varname>: Optional. If you need to be able to enable or disable
+interrupts from userspace by writing to <filename>/dev/uioX</filename>,
+you can implement this function. The parameter <varname>irq_on</varname>
+will be 0 to disable interrupts and 1 to enable them.
+</para></listitem>
</itemizedlist>
<para>