Linux

ext4 After the Stable Label

I have been testing ext4 on disposable filesystems for a while, but I have avoided recommending it for ordinary machines. Linux 2.6.28 was released on December 24 and removed ext4’s experimental designation. Only now am I comfortable calling it stable in the kernel sense, which is not the same as volunteering the only copy of my photographs.

The most visible change from ext3 is the use of extents. Rather than describing a large contiguous file as a long list of individual blocks, an extent describes a range. Large files need less metadata, and allocation can stay contiguous more easily. The on-disk format can also support much larger filesystems and files than ext3’s older structures comfortably allow.

Delayed allocation is another important piece. The filesystem can postpone the final block placement until dirty data is written, when it knows more about the size and neighboring writes. Combined with multiblock allocation, this can reduce fragmentation and improve throughput. The tradeoff is that allocation and write timing differ from ext3, so applications that confuse close() with durable storage may have their assumptions exposed.

The journal still protects filesystem metadata, but it is not a magical backup and does not promise that every recently written byte survives a crash. Applications that require ordering and durability need to use the proper synchronization operations and safe replacement patterns. A stable filesystem cannot repair an application protocol that never asked data to reach the disk.

Migration is possible because ext4 grew from ext3, but enabling new features changes what older kernels and tools can understand. I prefer creating a fresh ext4 filesystem for serious evaluation rather than turning an existing one into an archaeology project. Current e2fsprogs support is as important as kernel support, especially when the machine fails to boot and the rescue environment suddenly becomes relevant.

My cautious plan is to use ext4 first for build trees and other replaceable data, with backups and a recent kernel. If that remains boring, it can graduate to less disposable machines. I strongly prefer its extent-based direction over stretching ext3 forever, but five days with a stable label is not decades of field experience.

So ext4 is stable now, after December 24, 2008. It is also new, complex software in the least amusing place to discover a bug. Both statements can be true, and my backup disk does not mind the apparent indecision.

KDE 4.1 Feels Like a Desktop Again

I installed KDE 4.0 on a spare partition earlier this year and lasted about two days. It was interesting in the same sense that taking apart a toaster is interesting: there were clever pieces everywhere, but I still could not make breakfast.

KDE 4.1 is different. I have been using it for ordinary work since the release and, for the first time, I am spending more time in applications than arranging the desktop around them. That sounds like faint praise. For a desktop, however, becoming boring enough to disappear is a real achievement.

The panel is finally manageable. I can resize it, move it, add launchers and arrange the system tray without feeling that I am negotiating with a prototype. Plasma still exposes some rough edges, especially when widgets make optimistic assumptions about available space, but the basic shell now holds together.

KWin’s compositing also behaves much better on my Intel machine. Effects are not the important part; being able to leave compositing enabled without wondering whether the next window resize will turn into a slide show is. The new cover switch is amusing for several minutes, while smoother painting remains useful all day.

Dolphin has improved enough that I no longer immediately start Konqueror for every file operation. The tree view, tabs and saner selection behavior remove many small annoyances. There are still missing conveniences from KDE 3.5, and anyone depending on a particular panel applet should check before moving. “Newer” is not a substitute for “contains the thing I need.”

What changed my mind is not one large feature. It is the accumulation of small repairs: configuration modules that work, widgets that remember where they belong, fewer painting glitches and applications that look like parts of the same system. KDE 4’s new architecture was always ambitious; 4.1 is where some of that ambition starts paying rent.

I would now choose 4.1 for a machine I use myself, with a KDE 3.5 session nearby for emergencies. I would not yet migrate a room full of people who regard a moved icon as a personal attack. Progress is real, but so are users.

Idle Host, Busy Guest

My laptop stayed warm with an apparently idle KVM guest running. The guest reported nearly no processor use, and the host showed only small bursts, so I first blamed inaccurate temperature sensors. Sensors are convenient suspects because they cannot write rebuttals.

I stopped services in the guest one by one. A periodic timer user was waking it frequently, but even a minimal guest produced more activity than expected. Virtual timer interrupts, emulated devices and host-side handling all require exits from guest execution. An idle guest is therefore not necessarily an idle host.

Tickless operation helps when the guest kernel can avoid unnecessary periodic ticks and when KVM presents timers accurately enough for longer idle periods. It cannot eliminate device emulation or a program requesting frequent wakeups. The host must also be tickless while idle; saving ticks in one layer and generating them in the other is elaborate bookkeeping, not power management.

After using a tickless guest kernel and disabling a polling monitor, host wakeups dropped and the machine cooled. Timekeeping remained the thing to watch: aggressive experiments are worthless if the guest clock drifts or timers fire late.

My conclusion is to shut down unused guests on battery and to measure host wakeups, not merely guest CPU percentage. For a guest that must remain available, remove polling and use appropriate virtual devices where supported. Virtualization can make a machine appear to be doing nothing in two operating systems simultaneously while the processor is, with admirable professionalism, doing work for both.

When Rendering Bugs Move

A Qt application of mine began drawing stale text after I scrolled a custom widget. The bug appeared only with desktop compositing enabled, so I immediately blamed the driver. Then I ran it on a different card and saw the same stale text in a slightly different place.

My naive fix was to call update() repeatedly after scrolling. That reduced the frequency without curing it. Repainting more often can hide an invalid region briefly, but it cannot make incorrect geometry correct.

I reduced the widget until it painted only two rectangles and a label. The problem remained when one rectangle moved outside the area returned by the widget’s internal item bounds. My clipping assumptions were wrong: I invalidated the old logical rectangle but painted a pen and text extending beyond it. Compositing changed timing and exposure enough to reveal the mistake more reliably.

After expanding the dirty region to include every painted pixel, both drivers behaved. I then tested without compositing, with XRender compositing and with OpenGL compositing. That matrix is useful because a defect that follows one backend suggests a different layer from a defect that follows the application everywhere.

Adding a plain background behind the moving item made stale areas obvious and gave the reduced test a result anyone could recognize immediately.

Driver debugging still requires exact information. Card family, kernel module, X driver, Mesa version, colour depth and compositor backend can all matter. “Latest driver” is not a version, especially a week later. A minimal program is worth far more than a description of a large application that sometimes looks odd.

The most useful distinction is between wrong commands and wrong execution. If the application issues the wrong clipping, geometry or lifetime operations, changing drivers may only move the symptom. If a tiny correct sequence fails on one driver and succeeds elsewhere, the driver report becomes persuasive.

My practical conclusion is to simplify before assigning blame. Disable layers one at a time, record the exact matrix, and inspect the application’s painted bounds even when hardware acceleration appears implicated. Graphics stacks are complicated enough without accusing the innocent portion first. Unfortunately, every portion has previous convictions.

Trying Control Groups After 2.6.24

I wanted a compile job and its helper processes to stop overwhelming everything else on my test machine. Renicing the shell helped until the build launched processes with behavior I had not accounted for, and it did nothing about memory consumption.

Linux 2.6.24 includes the control groups framework, so I enabled the relevant options and mounted a control-group filesystem for testing. My first attempt was to write the compiler’s process ID into a group after the build had started. Some children were already elsewhere, and the result was inconsistent enough to look supernatural.

A control group is a hierarchy used to classify tasks. Controllers attach particular resource policies or accounting to that hierarchy. The framework itself is not one universal “make this process small” knob. CPU scheduling, processor sets and other controllers expose different files and semantics. A task belongs to a group in a hierarchy, and children normally inherit membership, so classification should happen before launching the workload.

I created a group, moved my test shell into it, and then started the build from that shell. Its descendants appeared in the same group. Applying CPU scheduling controls made the machine more responsive under contention without changing every process individually. Memory control is a separate matter and depends on kernel configuration; enabling it also has overhead that should not be waved away.

The hierarchy is powerful but easy to design badly. Groups may represent users, services or workloads, and those choices do not always nest neatly. Multiple hierarchies can attach different controllers, which provides flexibility at the cost of another opportunity to create an administrative puzzle.

For now I regard cgroups as kernel machinery for building resource-management policy, not as a finished desktop feature. The interface is low-level and sharp-edged. Tools will need to create groups, place tasks early, apply limits coherently and clean up afterward.

My practical conclusion is to start with one measured problem and one controller. Verify membership before interpreting results, and do not confuse accounting with enforcement. Cgroups can organize a family of processes in a way nice alone cannot. They can also organize one’s mistakes into a tidy hierarchy, which is progress of a sort.