SIGBUS when writing to a wl_shm surface on a full tmpfs / ftruncate() vs fallocate()
ppaalanen at gmail.com
Thu Oct 17 09:24:28 CEST 2013
On Wed, 16 Oct 2013 19:29:47 +0200
Olivier BLIN <olivier.blin at softathome.com> wrote:
> 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
> 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?
I think this would be a good idea. I have hit the SIGBUS myself before,
and did not know about fallocate() and friends.
Does the glibc fallback still avoid the application dying on SIGBUS if
space runs out?
More information about the wayland-devel