Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Apr 2017 11:47:56 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Chris Torek <torek@mail.torek.net>
Cc:        ablacktshirt@gmail.com, ed@nuxi.nl, freebsd-hackers@freebsd.org, rysto32@gmail.com, vasanth.raonaik@gmail.com
Subject:   Re: Understanding the FreeBSD locking mechanism
Message-ID:  <20170410084756.GJ1788@kib.kiev.ua>
In-Reply-To: <201704100811.v3A8BP8B049595@elf.torek.net>
References:  <20170410071137.GH1788@kib.kiev.ua> <201704100811.v3A8BP8B049595@elf.torek.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Apr 10, 2017 at 01:11:25AM -0700, Chris Torek wrote:
> >Signal trampolines never were put on the kernel stack ...
> 
> Oops, right, not sure why I was thinking that.  However I would still
> prefer to have libc supply the trampoline address (the underlying
> signal system calls can do this, since until you are catching a
> signal in the first place, there is no need for a known-in-advance
> trampoline address).
I considered some variation of this scheme when I worked on the
non-executable stack support. AFAIR the reason why I decided not to do
this was that the kernel-injected signal trampoline is still needed
for backward ABI-compat. In other words, the shared page would be
still needed, and we would end up with both libc trampoline and kernel
trampoline, which felt somewhat excessive.

Selecting one scheme or another based e.g. on the binary osrel was too
fragile, e.g. new binary might have loaded old library, and the kernel
trampoline still must be present in this situation.

> What I meant was that it's a dreadful error to do, e.g.:
> 
> 	critical_enter();
> 	mtx_lock(mtx);
> 	...
> 	mtx_unlock(mtx);
> 	critical_exit();
> 
> but the other order (lock first, then enter/exit) is OK.  This
> is similar to the prohibition against obtaining a default mutex
> while holding a spin mutex.

Sure, this is a bug.  Debugging kernel would catch this, at least
mi_switch() asserts that td_critnest == 0 (technically it checks that
td_critnest == 1 but the thread lock is owned there).  So if such code tries
to lock contested mutex, the bug causes panic.

I am sorry my previous mail contained an error: the spinlock_enter() also
increments td_critnest.  Still, since interrupts are disabled, this is
mostly cosmetics.  The more important consequence is that critical_exit()
on spinlock unlock re-checks td_owepreempt and executes potential postponed
scheduling actions.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20170410084756.GJ1788>