Signal safety additions now in master

Matthew Dillon dillon at backplane.com
Tue Nov 12 16:27:45 PST 2019


Some fairly significant signal safety additions have been made to libc and
pthreads in master.  Anyone upgrading please note that you will need to do
a full world and kernel build.

The basis for this is that for a very long time we've had problems building
a number of large packages, in particular lang/mono and lang/rust.  The
builds would only succeed one time out of ten, or one time out of twenty,
and just fail to complete the rest of the time.  After a lot of messing
around we traced the failures down to signal safety issues in both libc
(primarily the malloc subsystem), but also pthreads (primarily mutex
recursions and deadlocks from signal handlers).

But not just these two applications.  Really any large, sophisticated
application that tries to implement any sort of signal-based asynchronous
garbage collection or other mechanism is stretching the limits and causing
issues.  As these applications become more sophisticated they begin not
only to trip over our library code, but their own code as well.  The result
is that some applications are just aren't as robust as we'd like them to be.

The basic problem with doing signal-safety is that it normally eats at
least two system calls, often in performance-critical code paths, as well
as messes with signal masks which can interfere with the expectations of
the application.  To solve the problem properly and be able to enable
signal safety across every important function in libc and pthreads I have
created another shared user/kernel memory mapping called 'lpmap', which is
similar to the upmap and kpmap, but which is able to give us a per-thread
interface.  lpmap is per-thread, upmap is per-process, and kpmap is
system-wide.

With this new mechanism signal safety is as easy as incrementing and
decrementing a variable in memory that the kernel also has access to and
can use to prevent posts during critical section of code.  The signal
safety now being tested in master uses this new mechanism.  Two new libc
routines have been created to support it:

https://leaf.dragonflybsd.org/cgi/web-man?command=sigblockall&section=ANY

The memory allocator and most internal mutex used by pthreads have been
wrapped with this functionality.  We couldn't do this without the 'lpmap',
it would just be too expensive otherwise.  Languages such as rust and mono
are now far more reliable because of this, and we continue to test other
applications.

The primary repo commits implementing this are shown below.  Note that
there are also some follow-up stability and cleanup commits to these:

https://gitweb.dragonflybsd.org/dragonfly.git/commit/721505dec240e78696660384d988da78813a33bd

https://gitweb.dragonflybsd.org/dragonfly.git/commit/64b5a8a550c3c782ab04d04d63723691ac054ffc

Master will see more commits in coming weeks wrapping more library code
and/or replacing existing uses of sigprocmask() system calls (particularly
in rtld) to improve performance.  sigblockall()/sigunblockall() is a much
cleaner mechanism.

-Matt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dragonflybsd.org/pipermail/users/attachments/20191112/a35c0c51/attachment.html>


More information about the Users mailing list