SIGBUS when writing to a wl_shm surface on a full tmpfs / ftruncate() vs fallocate()

Olivier BLIN olivier.blin at softathome.com
Wed Oct 16 19:29:47 CEST 2013


Hi,

When creating a wl_shm pool with os_create_anonymous_file(), the 
underlying storage file is created on a tmpfs, and its size is set with 
ftruncate().
Though, when the tmpfs isn't big enough to hold this file, there is no 
error at the pool creation, since it is handled as a sparse file and its 
size is not reserved on the filesystem.

This has nasty side-effects, the client using the wl_shm surface from 
this pool will happily continue to use it, and has no way to properly 
catch errors when writing to the surface.
The client will just receive a SIGBUS when writing to the shm surface, 
just after having drained the tmpfs of space.
In simple-shm, the crash usually occurs in the initial memset() just 
after the buffer creation, but for clients not doing an initial clear, 
the crash can occur in less obvious places, like 
pixman_image_composite() in my case.

A solution could be to pre-allocate the shm pool, by using fallocate() 
or posix_fallocate() instead of ftruncate().
On newer Linux kernels (>= 3.5), the fallocate() operation is optimized 
for tmpfs (kernel commit e2d12e22c59ce714008aa5266d769f8568d74eac), it 
mostly allocates the pages and marks them as dirty.

On older kernels, the fallocate() operation won't be supported on tmpfs, 
but the glibc will fallback on its internal implementation that fills 
with zero (glibc commit a95a608f1b07a5c6e562294c570e89645d9b6176 for the 
syscall support and older commit 
bb8e0116cd59b11053154fb4adbad9f06a344147 for the fallback).
uClibc git master also supports fallocate(), but it does not seem to 
have a fallback (uClibc commit 5643900913f64c00f1c2958914586708efa5a473).

Usages of ftruncate() and os_create_anonymous_file() are in wayland 
(wayland-cursor) and weston (shm clients, compositor-wayland, xkb keymap).
Some users are already doing a memset() on the full shm buffer after its 
creation, but still, crashing with a SIGBUS is not the nicest way to fail.

Having a small tmpfs is likely a common use in the embedded world, and 
it would be nice to avoid such obscure crashes if possible.
What do you think of using fallocate() when supported instead of 
ftruncate() in wayland/weston?

Cheers

-- 
Olivier Blin - SoftAtHome

This message and any attachments herein are confidential, intended solely for the addressees and are SoftAtHome.s ownership. Any unauthorized use or dissemination is prohibited. If you are not the intended addressee of this message, please cancel it immediately and inform the sender.
This message and any attachments herein are confidential, intended solely for the addressees and are SoftAtHome.s ownership. Any unauthorized use or dissemination is prohibited. If you are not the intended addressee of this message, please cancel it immediately and inform the sender.


More information about the wayland-devel mailing list