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