Skip to content

One number that froze an Intel desktop on FreeBSD 15.1

· 5 min read

Bottom line up front

On FreeBSD 15.1 with drm-612-kmod-6.12.85 from the default quarterly packages, a Broadwell laptop froze several times a day. The mouse cursor kept moving and nothing else did. The log said GPU HANG, in Xorg, kwin, Plasma, the browser and a 3D printing slicer.

The GPU was fine and so were the applications. The kernel driver reports a version number for its memory mapping interface, and on 15.1 it reports 5 when it should report 3. Mesa believes it and maps every graphics buffer through a path that FreeBSD 15.1 does not fully support.

drm-kmod already fixed this upstream, in a one-line commit described as a Vulkan fix. The fix is not yet in the quarterly packages. The patch and build scripts are in spagu/freebsd-drm-i915-gtt3.

What it looked like

The laptop is the Dell XPS 13 9343 from the touchpad and Wi-Fi panic posts, with Intel HD Graphics 5500 (Broadwell, PCI ID 8086:1616). The latest freeze came minutes after someone installed a slicer and opened a model:

drmn0: [drm] GPU HANG: ecode 8:1:85dfffff, in MainThread [100930]
drmn0: [drm] Resetting rcs0 for stopped heartbeat on rcs0
drmn0: [drm] Xorg[100930] context reset due to GPU hang
drmn0: [drm] orcaslicer_main[101248] context reset due to GPU hang

The driver reset the GPU, and Xorg survived, which is why the cursor still moved. The window manager, kwin_x11, did not recover. Its rendering context had been reset under it, and it sat at 100% CPU drawing nothing. Killing it and starting kwin_x11 --replace against the running X server brought the desktop back with every window still open.

That is a workaround. A GPU that hangs several times a day has a cause.

When it started

The system log has the answer. From late September to 10 October there is not a single GPU HANG. On 10 October at 22:14, pkg upgrade removed drm-66-kmod and installed drm-612-kmod, because the drm-kmod meta-package now points at 6.12. The first hang came ninety minutes later. In the month that followed there were 62.

So it is a regression between the 6.6 and 6.12 drivers. That narrows it down only a little: the two branches are years of Linux i915 development apart.

The GPU error state

i915 keeps a full dump of the last hang. On FreeBSD it is in the Linux-style debugfs, which needs mounting:

mount -t lindebugfs lindebugfs /mnt
dd if=/mnt/dri/0/i915_error_state of=error_state.txt bs=1m

cat gets Operation not supported from that file and dd does not. The dump decodes with intel_error_decode from intel-gpu-tools. The part that matters:

IPEHR: 0x7a000004        PIPE_CONTROL
INSTDONE: 0xffdffffb
    busy: CS
    busy: VS
BBADDR: 0x0000fffe_fe5600d8

The application's batch buffer was small and ordinary: state setup and one 3DPRIMITIVE drawing four vertices, a rectangle. The command streamer went through all of it, up to MI_BATCH_BUFFER_END. Then the kernel's own PIPE_CONTROL, which waits for the GPU to finish, waited forever because the vertex shader never finished.

A correct batch that hangs while reading its inputs points at memory, not at the commands. The question becomes what changed in how buffers are mapped.

The number

The FreeBSD-specific changes between the drm-kmod 6.6 and 6.12 branches are a small fraction of the total. In i915_gem_mman.c, 6.6 has:

int i915_gem_mmap_gtt_version(void)
{
#ifdef __FreeBSD__not_yet
	return 4;
#else
	return 3;
#endif
}

and the 6.12 tag that the quarterly package is built from has:

#if __FreeBSD_version < 1500508 || (__FreeBSD_version >= 1600000 && __FreeBSD_version < 1600015)
	return 3;
#else
	return 5;
#endif

FreeBSD 15.1-RELEASE is 1501000. That is not below 1500508, and it is not in the 16-CURRENT range either, so 15.1 gets 5.

Mesa asks for this number with I915_PARAM_MMAP_GTT_VERSION. In intel_device_info.c:

devinfo->has_mmap_offset = val >= 4;
devinfo->has_partial_mmap_offset = val >= 5;

With has_mmap_offset set, both iris (OpenGL) and anv (Vulkan) stop using the legacy GEM_MMAP ioctl and map every buffer object through DRM_IOCTL_I915_GEM_MMAP_OFFSET, with write-back or write-combining caching. That is a different path through the kernel's page fault handling for every vertex buffer, texture and command buffer. On 6.6 the laptop never used it.

It was already fixed

The current drm-kmod tag, drm_v6.12.110_1, has this commit from 7 October:

-#if __FreeBSD_version < 1500508 || (__FreeBSD_version >= 1600000 && __FreeBSD_version < 1600015)
+#if __FreeBSD_version < 1500508 || (__FreeBSD_version >= 1501000 && __FreeBSD_version < 1600015)

Its message is "FreeBSD 15.1 doesn't support version 4 and 5 of gtt interface, keep using version 3 as otherwise it breaks vulkan." It says nothing about GPU hangs, and the open issue about them, drm-kmod #464, does not mention it either. People there report the same frozen screen with a moving cursor, and the workaround they share is going back to drm-66-kmod.

The latest ports branch has 6.12.110. The 2026Q4 quarterly branch, which is what pkg installs by default, still has drm_v6.12.85_3. Every FreeBSD 15.1 machine with an Intel GPU on default packages reports version 5.

Testing only that change

The fastest way to tell whether this is the cause is to change nothing else. build-i915-gtt3.sh takes the exact tag behind the installed package, applies the one line and builds only i915kms.ko, which takes about three minutes. No kernel rebuild is needed.

The result has the same size as the packaged module, and its code differs in one instruction:

i915_gem_mmap_gtt_version:   movl $0x5, %eax   ->   movl $0x3, %eax

install-i915-gtt3.sh creates a boot environment, keeps the packaged module as i915kms.ko.pkg-6.12.85_2 and installs the new one. The GPU driver cannot be swapped under a running X server, so it takes a reboot. Rolling back is one cp and another reboot.

What is proven and what is not

After the reboot, the slicer that had hung the GPU within minutes ran for over twenty minutes, and there has not been a single GPU HANG on any process. Before the change, this laptop hung several times on a normal day. One afternoon is a strong result, not a final one. A few days of ordinary use will settle it, and this post will be updated if the hangs come back.

This laptop is also only one machine and one GPU generation. The reports in #464 and the issues around it come from other Intel generations too. The mechanism would explain them as well, but each of those machines needs its own test.

What to do on 15.1 with an Intel GPU:

  • If the desktop freezes with a moving cursor, check grep 'GPU HANG' /var/log/messages.
  • Build graphics/drm-612-kmod from the latest ports branch, or use the scripts from the repository to patch the packaged version.
  • Lock the module against pkg upgrade until 6.12.110 reaches quarterly, because an upgrade puts the packaged module back.