|
|
Subscribe / Log in / New account

Kernel development

A Note to Kernel Page Readers

For the next two weeks, the normal Kernel Page editor will be away having a good time on the beach. Please bear with your temporary guest editor as he tries to make sense of the complexities of the Linux Kernel development process. A few of the below patches may be mis-categorized.

Comments (none posted)

Brief items

Kernel release status

The current development kernel is 2.5.74, which was released by Linus on July 2. The summary says: "Updates all over, the patch itself is big largely because of a MIPS/MIPS64 merge (and SH, for that matter). Network driver updates, USB updates, PnP, SCTP, s390, you name it. See the changelog for more details."

The current stable kernel is 2.4.21.

Marcelo has released the second 2.4.22 prepatch. This one includes some network driver updates, a big aic7xxx update, and many other fixes.

Comments (none posted)

Status 2.5

Guillaume Boissiere has posted a 2.5 status summary.

Full Story (comments: none)

2.5.73-mm3 Released

Andrew Morton has released 2.5.73-mm3.

Full Story (comments: none)

Kernel development news

perfctr-2.6.0-pre1 released

Mikael Pettersson has released a new version of perfctr, the Linux/x86 performance monitoring counters driver.

Full Story (comments: none)

Driver porting

Using read-copy-update

This article is part of the LWN Porting Drivers to 2.6 series.
Read-copy-update (RCU) is a mutual exclusion technique which can operate without locking most of the time. It can yield significant performance benefits when the data to be protected is accessed via a pointer, is read frequently, changed rarely, and references to the structure are not held while a kernel thread sleeps. The core idea behind RCU is that, when the data requires updating, a pointer to a new structure containing the new data can be stored immediately. The old structure containing the outdated data can then be freed at leisure, after it is certain that no process in the system holds a reference to that structure. For details on the ideas behind RCU, see this LWN article, or (for many details) this paper. Just don't ask SCO, even though they claim to own the technique.

The first step in using RCU within a subsystem is to define a structure containing the data to be protected. Often that structure already exists; for example, RCU has been retrofitted into the dentry cache (using struct dentry), the network routing cache (struct rtable), and several other, similar contexts. The structures need to be allocated dynamically and accessed via a pointer - RCU cannot be used with static structures.

Code which reads data structures protected by RCU need only take a couple of simple precautions:

  • A call to rcu_read_lock() should be made before accessing the data, and rcu_read_unlock() should be called afterward. This call disables preemption (and does nothing else) - a fast but necessary operation for RCU to work properly. These calls (along with the rest of the RCU definitions) are found in <linux/rcupdate.h>.

  • The code must not sleep while the "RCU read lock" is held.

Thus, code which reads an RCU-protected data structure will look something like:

    struct my_stuff *stuff;

    rcu_read_lock();
    stuff = find_the_stuff(args...);
    do_something_with(stuff);       /* Cannot sleep */
    do_something_else_with(stuff);  /* ditto        */
    rcu_read_unlock();

The write side of RCU is a little more complicated, but not that difficult. To update a data structure, the code starts by allocating a new copy of that structure, and filling in the new information. The code should then replace the pointer to the outdated structure with the new one, keeping a copy of the old pointer. After this operation, kernel code running on any other processor will find the new version of the structure. The old one cannot yet be freed, however, since it is possible that another processor is still using it.

The code should arrange to dispose of the old structure when it is known that it cannot be referenced anywhere else in the system. That is done through a call to call_rcu():

    void call_rcu(struct rcu_head *head, 
                  void (*func)(void *arg),
                  void *arg);

The calling code must provide an rcu_head structure, but need not initialize it in any way. Usually, that structure is embedded within the larger structure protected by RCU. The function func will be called when the structure can be safely freed, with arg as its one argument. All that func need do, normally, is call something like kfree() to free up the structure.

The RCU algorithm works by waiting until every processor in the system has scheduled at least once. Since the rules require that references to RCU-protected structures cannot be held over sleeps, no processor can possibly hold a reference to an old structure after it has scheduled. When all processors have scheduled (after the pointer change), references to the old structure can not exist, and the structure can be freed.

For what it's worth, the RCU code exports the "wait for everybody to schedule" functionality, should it be useful elsewhere. To perform this wait, one need only make a call to synchronize_kernel().

Comments (2 posted)

Patches and updates

Kernel trees

Stephen Hemminger 2..5.73-osdl2 ?
Stephen Hemminger 2.5.73-osdl3 ?
Marcelo Tosatti Linux 2.4.22-pre2 ?

Architecture-specific

Pasi Savolainen amd76x_pm for 2.5.73 ?
Martin Schwidefsky s390 patches: description. ?
Martin Schwidefsky s390 (1/7): base fix. ?
Martin Schwidefsky s390 (2/7): 31 bit compat. ?
Martin Schwidefsky s390 (3/7): common i/o layer. ?
Martin Schwidefsky s390 (4/7): dasd driver. ?
Martin Schwidefsky s390 (5/7): set module owner. ?
Martin Schwidefsky s390 (6/7): typos. ?
Martin Schwidefsky s390 (7/7): tty3215_init. ?
Martin Schwidefsky s390 2.5.73 take 2: description. ?
Martin Schwidefsky s390 (1/6): semtimedop. ?
Martin Schwidefsky PATCH] s390 (2/6): ptrace. ?
Martin Schwidefsky s390 (3/6): online attribute. ?
Martin Schwidefsky s390 (4/6): processor type. ?
Martin Schwidefsky s390 (5/6): thin interrupts. ?
J.A. Magallon kill extra printk prototype ?
Rusty Russell Get rid of __syscall_count. ?

Build system

Core kernel code

Development tools

Fabrice Bellard QEMU 0.4 release ?

Device drivers

Documentation

Francois Gouget Spelling fixes ?

Filesystems and block I/O

Memory management

Joe Thornber dm: fix memory leak ?
Joe Thornber dm: avoid event race ?
Joe Thornber dm: v4 ioctl interface ?
Marc-Christian Petersen [RESEND 4th] Fix oom killer braindamage ?

Networking

Benchmarks and bugs

Miscellaneous

Page editor: Forrest Cook
Next page: Distributions>>


Copyright © 2003, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds