Compiler have a precise knowledge of the content of sched_pin() and

sched_unpin() as they are functions static and inline.  This way it
can do two dangerous things:
- Reorder instructions around both of them, taking out from the safe
  path operations that are supposed to be (ie. per-cpu accesses)
- Cache the value of td_pinned in CPU registers not making visible
  in kernel context to the scheduler once it is scanning the runqueue,
  as td_pinned is not marked volatile.

In order to avoid both possible bugs explicitly, protect the safe path
with compiler memory barriers. This will prevent reordering and caching
by the compiler about td_pinned operations.

Generally this could lead to suboptimal code traversing the pinnings
but this is not the case as can be easilly verified:
http://lists.freebsd.org/pipermail/svn-src-projects/2012-October/005797.html

Discussed with:	jeff, jhb
MFC after:	2 weeks
This commit is contained in:
attilio 2012-10-29 01:35:17 +00:00
parent d209784979
commit f3a86755d7

View File

@ -151,11 +151,13 @@ static __inline void
sched_pin(void)
{
curthread->td_pinned++;
__compiler_membar();
}
static __inline void
sched_unpin(void)
{
__compiler_membar();
curthread->td_pinned--;
}