Re: [PATCH 14/25] Docs: kernel-hacking: Rewrite local_irq_{disable,enable,save,restore}

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 27 Feb 2010 07:10:57 +0000 Michael Witten wrote:

> 
> This section has been greatly expanded and clarified.
> 
> Signed-off-by: Michael Witten <mfwitten@xxxxxxxxx>
> ---
>  Documentation/DocBook/kernel-hacking.tmpl |  112 +++++++++++++++++++++++++++--
>  1 files changed, 106 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
> index aaf2be4..37901b9 100644
> --- a/Documentation/DocBook/kernel-hacking.tmpl
> +++ b/Documentation/DocBook/kernel-hacking.tmpl
> @@ -679,11 +679,111 @@
>     </title>
>  
> -   <para>
> -    These routines disable hard[ware] interrupts on the local CPU, and
> -    restore them.  They are reentrant; saving the previous state in
> -    their one <varname>unsigned long flags</varname> argument.  If you
> -    know that interrupts are enabled, you can simply use
> -    <function>local_irq_disable()</function> and
> -    <function>local_irq_enable()</function>.
> -   </para>
> +   <para>
> +    With respect to a CPU instruction, a <firstterm>local CPU</firstterm> is
> +    a CPU that is executing that instruction.
> +   </para>
> +
> +   <para>
> +    Often, it is important to be able to execute a sequence of instructions
> +    with the assurance that the corresponding local CPU won't be interrupted
> +    until it has completed executing that sequence of instructions; under
> +    these needs, such a sequence of instructions is considered as a whole to
> +    be <firstterm>locally atomic</firstterm> (that is, 'indivisible' on the
> +    corresponding local CPU). The routines discussed here are helpful in
> +    creating such <firstterm>local atomicity</firstterm>.
> +   </para>
> +
> +   <para>
> +    The main purpose of these routines is to affect how a
> +    local CPU treats hard[ware] interrupts: By executing
> +    <function>local_irq_disable()</function>, a local CPU is instructed
> +    to ignore hard interrupts; by executing
> +    <function>local_irq_enable()</function>, a local CPU is instructed
> +    to respond to hard interrupts. Consequently, in the simplest case,
> +    a block of code can be rendered locally atomic by placing
> +    <function>local_irq_disable()</function> before the block and
> +    <function>local_irq_enable()</function> after the block.
> +   </para>
> +
> +   <para>
> +    However, what if one such locally atomic block calls a function that runs
> +    another such locally atomic block? In that case, this latter block
> +    might run <function>local_irq_enable()</function>
> +    before the first block finishes, thereby ruining the local atomicity
> +    of the first block.
> +   </para>
> +
> +   <para>
> +    This problem can be solved by noting whether a local CPU is already
> +    ignoring hard interrupts when entering a locally atomic block, and then
> +    restoring that same status upon exiting the block, all of which
> +    can be achieved by replacing
> +    <function>local_irq_{disable,enable}()</function> with
> +    <function>local_irq_{save,restore}(<varname>flags</varname>)</function>
> +    macros, where <varname>flags</varname> is a user-supplied stack-allocated
> +    variable of type <emphasis>unsigned long</emphasis>
> +    (note: it's <emphasis>not</emphasis> a pointer type).
> +   </para>
> +
> +   <para>
> +    The <function>local_irq_save(<varname>flags</varname>)</function> macro
> +    exands around the <varname>flags</varname> variable to perform 2 tasks

       expands

> +    on a local CPU:
> +   </para>
> +
> +   <itemizedlist>
> +    <listitem>
> +     <para>
> +      The local CPU's relevant processor-state bits (including
> +      <emphasis>at least</emphasis> those that affect hard interrupts) are
> +      stored in <varname>flags</varname>.
> +     </para>
> +    </listitem>
> +    <listitem>
> +     <para>
> +      The local CPU is instructed to ignore hard interrupts; essentially
> +      a call to <function>local_irq_disable()</function> is made.
> +     </para>
> +    </listitem>
> +   </itemizedlist>
> +
> +   <para>
> +    The <function>local_irq_restore(<varname>flags</varname>)</function> macro
> +    exands to instruct a local CPU to use as its relevant processor-state bits

       expands

I updated both of these in my local patch queue.

> +    the values stored in the <varname>flags</varname> variable.
> +   </para>
> +
> +   <para>
> +    Hence, if a local CPU is already ignoring hard interrupts when
> +    <function>local_irq_save(<varname>flags</varname>)</function> is used,
> +    then that local CPU will continue to ignore hard interrupts when the
> +    corresponding
> +    <function>local_irq_restore(<varname>flags</varname>)</function> is
> +    used, thereby allowing for the nesting of locally atomic blocks. However,
> +    if a local CPU is responding to hard interrupts when
> +    <function>local_irq_save(<varname>flags</varname>)</function> is used,
> +    then that local CPU will once again respond to hard interrupts when
> +    the corresponding
> +    <function>local_irq_restore(<varname>flags</varname>)</function>
> +    is used, as if a call to <function>local_irq_enable()</function>
> +    has been made.
> +   </para>
> +
> +   <para>
> +    Of course,
> +    <function>local_irq_{save,restore}(<varname>flags</varname>)</function>
> +    are more expensive in time and space than are
> +    <function>local_irq_{disable,enable}()</function>. Consequently,
> +    the latter should be used when it makes sense to do so.
> +   </para>
> +
> +   <para>
> +    These macros/functions are reentrant.
> +   </para>
> +
> +   <para>
> +    There are also other means by which kernel code can achieve synchronization
> +    and atomicity through locking mechanisms, and they are especially important
> +    for code that may run concurrently across multiple CPUs.
> +   </para>
>    </sect1>
> -- 


---
~Randy
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux