Blog

Linux 2.6.0 Arrives

Linux 2.6.0 was released yesterday. After the long 2.5 development series and months of test releases, there is finally a version number administrators can put into a plan without the word “test” in it. This does not mean I am replacing every 2.4 kernel before lunch. It means the migration can become deliberate rather than hypothetical.

The itch for me is desktop latency. My machine compiles, plays audio, runs KDE, and occasionally receives the unreasonable request to respond to the keyboard at the same time. Linux 2.6 has two important mechanisms for that: the O(1) scheduler and optional kernel preemption.

The scheduler keeps per-CPU active and expired priority arrays. Selecting the next task does not require scanning a growing list of runnable processes, and interactive tasks receive dynamic priority treatment based largely on sleep behaviour. Preemption goes a step further. When enabled, kernel code that is not in a critical section can be preempted, reducing the time a newly runnable high-priority task waits for a long kernel path to finish.

Neither feature creates free CPU time. A saturated machine remains saturated, and a bad driver can still ruin the afternoon. What changes is how predictably the system gives urgent work a turn.

Threading is another substantial improvement. The kernel facilities used by NPTL provide proper thread groups, efficient futex-based synchronization, and saner signal and process semantics than LinuxThreads could offer. A POSIX mutex can complete entirely in userspace when uncontended and enter the kernel only to wait or wake when there is contention. This matters both for performance and for making tools show one multithreaded process as something resembling one multithreaded process.

The device model may have the largest administrative consequence. Sysfs exposes devices, buses, classes, and drivers as related kernel objects under /sys. The kernel now has a coherent answer to questions such as “what is this device attached to?” instead of scattering hints across boot messages and /proc.

That structure makes userspace device management practical. Early work on udev can listen for hotplug events, consult sysfs, and create device nodes according to userspace policy. I am not ready to discard a working /dev setup everywhere, but moving naming policy out of the kernel is the right direction. Hardware discovery belongs in the kernel; deciding that a particular camera should have a friendly local name does not.

There are less glamorous changes that may matter more on servers. The block I/O layer and filesystem scalability have received major work. The kernel supports larger systems, more processors, and more memory without treating each as a surprising edge case. Native ALSA support gives sound users a maintained kernel interface, though moving from OSS drivers may require mixer and application adjustments.

The migration is not just a kernel file

My safe upgrade recipe begins by leaving 2.4 intact. I install 2.6 under a distinct name, add a separate boot-loader entry, and verify that selecting the old entry still works. The new kernel image is the easiest part to roll back; userspace and configuration changes require more thought.

Linux 2.6 modules use a different format, so module-init-tools must be installed. The tools are designed to coexist with the programs needed by 2.4, which is exactly what a gradual migration needs. Recent versions of procps, filesystem utilities, and other low-level packages are also worth checking against the distribution’s recommendations.

For a first boot I compile the root disk controller and root filesystem into the kernel. Once the machine boots reliably, I can introduce an initial ramdisk and modularise things. Debugging one new mechanism at a time is slower only until the first failure.

I also mount sysfs explicitly if the startup scripts do not:

mount -t sysfs none /sys

Then I test the boring list: all filesystems, swap, networking, firewall rules, sound, removable devices, suspend if the machine uses it, and clean shutdown. I compare dmesg for errors rather than merely noticing that a login prompt appeared. A successful boot proves the boot path, not the rest of the computer.

Out-of-tree drivers are the largest caveat. The internal kernel interfaces have changed, sometimes substantially, and a driver compiling on 2.4 says nothing about 2.6. Binary-only modules are especially dependent on their vendor producing a matching build. Before an upgrade, inventory these modules with the same seriousness as storage hardware.

Applications should generally continue to run. This is not a new userspace ABI. Problems are more likely to come from programs that inspect /proc, rely on old thread display details, expect OSS device behaviour, or invoke module utilities directly.

My opinion is that 2.6 is a stronger foundation, especially for interactive systems and machines with many tasks or processors. But .0 is a milestone, not a papal declaration of perfection. Production systems deserve a soak period, distribution patches, and testing against their actual workload.

I will install it quickly on my workstation and slowly on servers. This is not inconsistency. The workstation can inconvenience me; the server can introduce me to several irritated people at once. Linux 2.6.0 is ready for serious testing today, and with cautious migration it should become the ordinary kernel soon enough.

Trying the KDE 3.2 Beta

I have been running the KDE 3.2 beta on a spare account because I wanted to see whether the next release changes daily work or merely rearranges the furniture. KDE 3.1 is already a comfortable desktop, so additions now have to earn their place.

The most visible newcomer is Kontact, which presents mail, calendar, contacts, and related information in one shell. The important word is “presents.” It is integrating existing KDE PIM components rather than replacing every application with one enormous program. KMail still behaves like KMail, but I can move between mail and appointments without managing a row of separate top-level windows.

Konqueror and KHTML also continue to improve. Pages that used to expose small layout failures are behaving better, and Safari’s use of KHTML has clearly raised both attention and expectations. I would not claim identical rendering: the engines have already diverged in places, platform code differs, and a site can always find a novel way to be broken. Still, more real-world testing is showing.

The obvious test procedure is not to click around for ten minutes and declare victory. I copied my normal profile, used it for several days, and watched the console output. I tested IMAP folders, printing, file previews, keyboard shortcuts, and the few unpleasant web applications I cannot avoid. Pretty menus are easy; preserving mail and settings is the examination.

Anyone trying a beta should keep a separate home directory or at least a backup of .kde. Configuration files can be upgraded, plugins built for another KDE release may not load, and returning to 3.1 after writing new settings is not guaranteed to be graceful. A beta is an offer to find bugs, not an unusually exciting package update.

My impression so far is that 3.2 is becoming more coherent rather than merely larger. That distinction matters. KDE has no shortage of features. What it needs is for related features to fit together, for defaults to be sensible, and for common paths to require less ceremony.

Kontact is a good example of the right sort of integration: reuse the specialised applications and give them a shared front door. If the remaining beta period concentrates on reliability, 3.2 should be a worthwhile upgrade. If it concentrates on adding twelve more buttons, I reserve the right to hide the toolbars and sulk.

Reading the Device Tree in sysfs

I needed to answer a simple question on a 2.6 test machine: which driver owns this network device? My old habit was to rummage through boot messages, /proc, and module output until the answer surrendered. The new device model gives us a less archaeological method.

First, mount sysfs if the installation has not done it already:

mount -t sysfs none /sys

The interesting part is not that /sys contains files. Linux can turn almost anything into files if left unattended. The useful part is the structure. Devices appear according to their physical or logical parentage under /sys/devices. Buses, such as PCI and USB, have views under /sys/bus, while /sys/class groups devices by function, such as network interfaces or block devices.

These are views of the same kernel objects, joined by symbolic links. For an Ethernet interface named eth0, this is a useful start:

readlink /sys/class/net/eth0/device
ls -l /sys/class/net/eth0/device/driver

The first link leads back into the device hierarchy. The driver link, when present, identifies the bound driver. Following parent links tells me which PCI device contains the interface and where that device sits.

This differs from /proc. Procfs grew as a place for process information and gradually acquired assorted kernel knobs and device facts. Sysfs is an exported representation of the kernel’s device model. One attribute per file is the usual convention, which makes simple scripts possible without parsing a decorative essay from the kernel.

I am deliberately cautious about those scripts. The 2.6 series is not final yet, and sysfs details can change as interfaces settle. Scripts should consume documented attributes, not depend on directory ordering or infer meaning from every internal-looking name. A readable tree is still an interface, not an invitation to marry the first implementation detail one encounters.

The larger implication is device management in userspace. If the kernel exposes device identity and events cleanly, a userspace program can create names and permissions according to policy rather than a huge static /dev or a kernel naming scheme. That work is still young, but sysfs supplies the map it needs.

For now, it has already replaced several minutes of log-diving with two symbolic links. I consider that progress, even if it has added another virtual filesystem to my vocabulary.

NPTL and the Disappearing Processes

I upgraded a test machine to a recent glibc with NPTL and immediately thought several processes had disappeared. An old LinuxThreads program used to make ps look as if every thread had invited itself to the process list. With NPTL and updated tools, the display is much closer to what the programmer meant: one process containing several threads.

The old implementation was clever, but its compromises leaked. LinuxThreads created tasks with clone() and used a manager thread for coordination. Thread IDs and process IDs did not line up neatly with POSIX expectations, signal delivery had awkward corners, and tools often presented threads as peculiar sibling processes.

NPTL also builds threads on kernel tasks, but newer kernel facilities let it implement POSIX semantics much more directly. Thread groups identify tasks belonging to one process. Futexes provide a fast synchronization primitive: uncontended locking can happen in userspace, while the kernel becomes involved when a thread must sleep or wake another waiter. That avoids a system call for every successful mutex operation.

The practical lesson is to upgrade the tools with the library. A stale ps, debugger, or monitoring script can report technically available data in a thoroughly unhelpful way. On this machine I check both the process view and the individual tasks under /proc/PID/task when debugging:

ls /proc/1234/task

Each directory there is a kernel task ID. The process has a thread-group leader, and the other tasks share resources according to the flags used when they were created. “Thread” is not a completely separate kernel creature. It is a task sharing an address space and other state with its group.

Compatibility deserves some attention too. Programs should use the POSIX thread API and not depend on LinuxThreads accidents such as each thread appearing to have an unrelated process identity. Code that sends signals to guessed numeric IDs is especially suspicious. Correct code generally needs no source change, but incorrect assumptions have enjoyed years to become tradition.

NPTL is faster in useful places, particularly thread creation and synchronization, but I like the semantic cleanup more. Better benchmarks are welcome; fewer explanations beginning with “well, on Linux a thread looks like…” are better. The implementation is finally making the common abstraction less dishonest.

Qt Layouts Before Pixel Pushing

I fixed a dialog today that looked fine in English and ridiculous in German. The original code positioned every Qt widget with coordinates, so a longer label pushed straight through the line edit beside it. Apparently translations had failed to respect our geometry. Very inconsiderate of them.

The obvious fix was not to adjust the numbers. It was to remove them.

In Qt 3, layouts already know how to negotiate widget sizes. A QVBoxLayout stacks rows, a QHBoxLayout arranges each row, and QGridLayout handles label-and-field forms without pretending every label has the same width.

QGridLayout *layout = new QGridLayout(this, 2, 2, 8, 6);
layout->addWidget(new QLabel(tr("Server name:"), this), 0, 0);
layout->addWidget(serverEdit, 0, 1);
layout->addWidget(new QLabel(tr("User:"), this), 1, 0);
layout->addWidget(userEdit, 1, 1);
layout->setColStretch(1, 1);

The margins and spacing remain explicit, but the widgets provide size hints and the second column absorbs extra room. The dialog now survives longer translations, a different font, and a user resizing it.

One small trap is mixing layouts with manual setGeometry() calls on the same children. The layout will win, usually just after the hand-tuned version looked correct on the developer’s machine.

I still use fixed sizes when the thing really is fixed, such as a small colour swatch. For forms and text, coordinates are merely tomorrow’s bug written as two integers. Let the layout do the dull arithmetic. It has more patience than I do.