<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
<book id="lk-hacking-guide">
<bookinfo>
<title>Unreliable Guide To Hacking The Linux Kernel</title>
<authorgroup>
<author>
<firstname>Paul</firstname>
<othername>Rusty</othername>
<surname>Russell</surname>
<affiliation>
<address>
<email>rusty@rustcorp.com.au</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2001</year>
<holder>Rusty Russell</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
</para>
<para>
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
</para>
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
</para>
<para>
For more details see the file COPYING in the source
distribution of Linux.
</para>
</legalnotice>
<releaseinfo>
This is the first release of this document as part of the kernel tarball.
</releaseinfo>
</bookinfo>
<toc></toc>
<chapter id="introduction">
<title>Introduction</title>
<para>
Welcome, gentle reader, to Rusty's Unreliable Guide to Linux
Kernel Hacking. This document describes the common routines and
general requirements for kernel code: its goal is to serve as a
primer for Linux kernel development for experienced C
programmers. I avoid implementation details: that's what the
code is for, and I ignore whole tracts of useful routines.
</para>
<para>
Before you read this, please understand that I never wanted to
write this document, being grossly under-qualified, but I always
wanted to read it, and this was the only way. I hope it will
grow into a compendium of best practice, common starting points
and random information.
</para>
</chapter>
<chapter id="basic-players">
<title>The Players</title>
<para>
At any time each of the CPUs in a system can be:
</para>
<itemizedlist>
<listitem>
<para>
not associated with any process, serving a hardware interrupt;
</para>
</listitem>
<listitem>
<para>
not associated with any process, serving a softirq, tasklet or bh;
</para>
</listitem>
<listitem>
<para>
running in kernel space, associated with a process;
</para>
</listitem>
<listitem>
<para>
running a process in user space.
</para>
</listitem>
</itemizedlist>
<para>
There is a strict ordering between these: other than the last
category (userspace) each can only be pre-empted by those above.
For example, while a softirq is running on a CPU, no other
softirq will pre-empt it, but a hardware interrupt can. However,
any other CPUs in the system execute independently.
</para>
<para>
We'll see a number of ways that the user context can block
interrupts, to become truly non-preemptable.
</para>
<sect1 id="basics-usercontext">
<title>User Context</title>
<para>
User context is when you are coming in from a system call or
other trap: you can sleep, and you own the CPU (except for
interrupts) until you call <function>schedule()</function>.
In other words, user context (unlike userspace) is not pre-emptable.
</para>
<note>
<para>
You are always in user context on module load and unload,
and on operations on the block device layer.
</para>
</note>
<para>
In user context, the <varname>current</varname> pointer (indicating
the task we are currently executing) is valid, and
<function>in_interrupt()</function>
(<filename>include/linux/interrupt.h</filename>) is <returnvalue>false
</returnvalue>.
</para>
<caution>
<para>
Beware that if you have interrupts or bottom halves disabled
(see below), <function>in_interrupt()</function> will return a
false positive.
</para>
</caution>
</sect1>
<sect1 id="basics-hardirqs">
<title>Hardware Interrupts (Hard IRQs)</title>
<para>
Timer ticks, <hardware>network cards</hardware> and
<hardware>keyboard</hardware> are examples of real
hardware which produce interrupts at any time. The kernel runs
interrupt handlers, which services the hardware. The kernel
guarantees that this handler is never re-entered: if another
interrupt arrives, it is queued (or dropped). Because it
disables interrupts, this handler has to be fast: frequently it
simply acknowledges the interrupt, marks a `software interrupt'
for execution and exits.
</para>
<para>
You can tell you are in a hardware interrupt, because
<function>in_irq()</function> returns <returnvalue>true</returnvalue>.
</para>
<caution>
<para>
Beware that this will return a false positive if interrupts are disabled