Bug 9011

Summary: kernel-locking.tmpl has incorrect and oversimplified information
Product: Other Reporter: Matti Linnanvuori (mattilinnanvuori)
Component: OtherAssignee: other_other
Status: RESOLVED PATCH_ALREADY_AVAILABLE    
Severity: low CC: rdunlap
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 2.6.23-rc6-git1 Subsystem:
Regression: --- Bisected commit-id:

Description Matti Linnanvuori 2007-09-12 09:55:07 UTC
Most recent kernel where this bug did not occur: unknown
Problem Description: kernel-locking.tmpl has incorrect path linux/asm/semaphore.h and oversimplified information about locks. The kernel lacks documentation about try functions.

Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

--- linux-2.6.23/Documentation/DocBook/kernel-locking.tmpl	2007-09-12 18:24:20.395574500 +0300
+++ linux-2.6.23-patched/Documentation/DocBook/kernel-locking.tmpl	2007-09-12 19:22:28.425442500 +0300
@@ -225,27 +225,39 @@
      There are three 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 
-     spinlock, you keep trying (spinning) until you can.  Spinlocks are 
+     which is a very simple single-holder lock. If you can't get the 
+     spinlock with <function>spin_lock</function> at any try, you
+     keep retrying (spinning) until you can.
+     <function>spin_trylock</function> does not spin but returns nonzero if it
+     could get the spinlock at the first try or 0 if not.  Spinlocks are
      very small and fast, and can be used anywhere.
    </para>
    <para>
      The second type is a mutex
      (<filename class="headerfile">include/linux/mutex.h</filename>): it
      is like a spinlock, but you may block holding a mutex.
-     If you can't lock a mutex, your task will suspend itself, and be woken
+     If you can't lock a mutex with <function>mutex_lock</function>
+     at the first try, your task will suspend itself, and be woken 
      up when the mutex is released.  This means the CPU can do something
      else while you are waiting.  There are many cases when you simply
      can't sleep (see <xref linkend="sleeping-things"/>), and so have to
      use a spinlock instead.
+     <function>mutex_trylock</function> does not suspend your task
+     but returns nonzero if it could lock the mutex at the first try
+     or 0 if not.
    </para>
    <para>
      The third type is a semaphore
      (<filename class="headerfile">include/asm/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
+     single-holder lock (a mutex).  If you can't get a semaphore with 
+     <function>down</function> at the first try, your
      task will be suspended and later on woken up - just like for mutexes.
+     <function>down_trylock</function> does not suspend your task
+     but returns 0 if it could get the semaphore at the first try or
+     nonzero if not. The return value is the inverse of that of
+     spinlock and mutex.
    </para>
    <para>
      Neither type of lock is recursive: see
@@ -290,7 +302,7 @@
      <para>
        If you have a data structure which is only ever accessed from
        user context, then you can use a simple semaphore
-       (<filename>linux/asm/semaphore.h</filename>) to protect it.  This 
+       (<filename>include/asm/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
Comment 1 Matti Linnanvuori 2008-03-25 09:20:00 UTC
From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

Fix a wrong path. Add information about try functions.

Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

---

--- linux-2.6/Documentation/DocBook/kernel-locking.tmpl    2008-03-23 09:01:06.335759500 +0200
+++ linux/Documentation/DocBook/kernel-locking.tmpl    2008-03-25 18:13:39.703174500 +0200
@@ -225,27 +225,40 @@
      There are three 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 
-     spinlock, you keep trying (spinning) until you can.  Spinlocks are 
-     very small and fast, and can be used anywhere.
+     which is a very simple single-holder lock: if you can't get the
+     spinlock, you keep trying (spinning) until you can. The spinning function
+     is <function>spin_lock()</function>. <function>spin_trylock()</function>
+     does not spin but returns nonzero if you got the spinlock at the first try
+     or 0 if not. <function>spin_unlock()</function> releases the spin lock.
+     Spinlocks are very small and fast, and can be used anywhere.
    </para>
    <para>
      The second type is a mutex
      (<filename class="headerfile">include/linux/mutex.h</filename>): it
      is like a spinlock, but you may block holding a mutex.
-     If you can't lock a mutex, your task will suspend itself, and be woken
+     If you can't lock a mutex with <function>mutex_lock()</function>
+     at the first try, your task will suspend itself, and be woken
      up when the mutex is released.  This means the CPU can do something
      else while you are waiting.  There are many cases when you simply
      can't sleep (see <xref linkend="sleeping-things"/>), and so have to
      use a spinlock instead.
+     <function>mutex_trylock()</function> does not suspend your task
+     but returns nonzero if it could lock the mutex at the first try
+     or 0 if not.
    </para>
    <para>
      The third type is a semaphore
      (<filename class="headerfile">include/asm/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
+     single-holder lock (a mutex).  If you can't get a semaphore with
+     <function>down()</function> at the first try, your
      task will be suspended and later on woken up - just like for mutexes.
+     <function>down_trylock()</function> does not suspend your task
+     but returns 0 if it could get the semaphore at the first try or
+     nonzero if not. The return value is the inverse of that of
+     <function>spin_trylock()</function> and <function>mutex_trylock()
+     </function>.
    </para>
    <para>
      Neither type of lock is recursive: see
@@ -290,7 +303,7 @@
      <para>
        If you have a data structure which is only ever accessed from
        user context, then you can use a simple semaphore
-       (<filename>linux/asm/semaphore.h</filename>) to protect it.  This 
+       (<filename>include/asm/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 

---



      ____________________________________________________________________________________
Looking for last minute shopping deals?  
Find them fast with Yahoo! Search.  http://tools.search.yahoo.com/newsearch/category.php?category=shopping
Comment 2 Randy Dunlap 2008-03-25 11:25:22 UTC
Hi,

The documentation for the try() functions is important and so it's good to
add it, but the section where it is being added is a high-level, introductory
section about the three types of locking.  This introductory section shouldn't
go into details about trylock().  Please put that information somewhere else.
Comment 3 Matti Linnanvuori 2008-03-25 12:44:01 UTC
From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

Fix a wrong path. Add a chapter about try functions.

Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

---

--- linux-2.6/Documentation/DocBook/kernel-locking.tmpl    2008-03-23 09:01:06.335759500 +0200
+++ linux/Documentation/DocBook/kernel-locking.tmpl    2008-03-25 21:39:12.393324000 +0200
@@ -290,7 +290,7 @@
      <para>
        If you have a data structure which is only ever accessed from
        user context, then you can use a simple semaphore
-       (<filename>linux/asm/semaphore.h</filename>) to protect it.  This 
+       (<filename>include/asm/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 
@@ -703,6 +703,29 @@
 </sect1>
 </chapter>
 
+<chapter id="try-variants">
+ <title>The try variants</title>
+
+  <para>
+    <function>spin_trylock()</function> does not spin but returns nonzero if
+    you got the spinlock at the first try or 0 if not.
+  </para>
+
+  <para> 
+    <function>mutex_trylock()</function> does not suspend your task
+    but returns nonzero if it could lock the mutex at the first try
+    or 0 if not.
+  </para>
+
+  <para>
+    <function>down_trylock()</function> does not suspend your task
+    but returns 0 if it could get the semaphore at the first try or
+    nonzero if not. The return value is the inverse of that of
+    <function>spin_trylock()</function> and <function>mutex_trylock()
+    </function>.
+  </para>
+</chapter>
+
   <chapter id="Examples">
    <title>Common Examples</title>
     <para>





      ____________________________________________________________________________________
Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ
Comment 4 Randy Dunlap 2008-03-25 13:42:50 UTC
http://bugzilla.kernel.org/show_bug.cgi?id=9011

How about this one?



------- Comment #3 from mattilinnanvuori@yahoo.com  2008-03-25 12:44 -------
From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>

Fix a wrong path. Add a chapter about try functions.

Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>

---

---
 Documentation/DocBook/kernel-locking.tmpl |   25 +++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

--- lin2625-rc6g2.orig/Documentation/DocBook/kernel-locking.tmpl
+++ lin2625-rc6g2/Documentation/DocBook/kernel-locking.tmpl
@@ -290,7 +290,7 @@
      <para>
        If you have a data structure which is only ever accessed from
        user context, then you can use a simple semaphore
-       (<filename>linux/asm/semaphore.h</filename>) to protect it.  This 
+       (<filename>include/asm/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 
@@ -703,6 +703,29 @@
 </sect1>
 </chapter>
 
+<chapter id="try-variants">
+ <title>The try variants</title>
+
+  <para>
+    <function>spin_trylock()</function> does not spin but returns non-zero if
+    it acquires the spinlock on the first try or 0 if not.
+  </para>
+
+  <para>
+    <function>mutex_trylock()</function> does not suspend your task
+    but returns non-zero if it could lock the mutex on the first try
+    or 0 if not.
+  </para>
+
+  <para>
+    <function>down_trylock()</function> does not suspend your task
+    but returns 0 if it could get the semaphore on the first try or
+    non-zero if not. The return value is the inverse of that of
+    <function>spin_trylock()</function> and <function>mutex_trylock()
+    </function>.
+  </para>
+</chapter>
+
   <chapter id="Examples">
    <title>Common Examples</title>
     <para>
Comment 5 Matti Linnanvuori 2008-05-04 00:32:11 UTC
From: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
 
Add a chapter about trylock functions.
http://bugzilla.kernel.org/show_bug.cgi?id=9011
 
Signed-off-by: Matti Linnanvuori <mattilinnanvuori@yahoo.com>
 
---
 
--- 
linux-2.6/Documentation/DocBook/kernel-locking.tmpl 2008-05-04 
09:22:20.782075500 +0300
+++ 
linux/Documentation/DocBook/kernel-locking.tmpl 2008-05-04 10:13:16.168549500 
+0300
@@ -702,6 +702,38 
@@
 
 </sect1>
 </chapter>
+<chapter 
id="trylock-functions">
+ <title>The trylock 
Functions</title>
+  <para>
+   There are functions that try 
to acquire a lock only once and immediately
+   return a value telling about 
success or failure to acquire the lock.
+   They can be used if you need no 
access to the data protected with the lock
+   when some other thread is 
holding the lock. You should acquire the lock
+   later if you then need 
access to the data protected with the lock.
+  </para>
+
+  
<para>
+    <function>spin_trylock()</function> does not 
spin but returns non-zero if
+    it acquires the spinlock on the first try 
or 0 if not. This function can
+    be used in all contexts like 
<function>spin_lock</function>: you must have
+    disabled the 
contexts that might interrupt you and acquire the spin lock.
+  
</para>
+
+  <para>
+    
<function>mutex_trylock()</function> does not suspend your 
task
+    but returns non-zero if it could lock the mutex on the first 
try
+    or 0 if not. This function cannot be safely used in hardware or 
software 
+    interrupt contexts despite not sleeping.
+  
</para>
+
+  <para>
+    
<function>down_trylock()</function> does not suspend your 
task
+    but returns 0 if it could get the semaphore on the first try 
or
+    non-zero if not. The return value is the inverse of that of
+    
<function>spin_trylock()</function> and 
<function>mutex_trylock()
+    </function>. 
<function>down_trylock</function> can be used in all contexts.
+  
</para>
+</chapter>
 
   <chapter 
id="Examples">
    <title>Common 
Examples</title>



      ____________________________________________________________________________________
Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ