Messages in this thread | | | Date | Mon, 16 May 2016 13:00:54 +0200 | From | Peter Zijlstra <> | Subject | Re: Additional compiler barrier required in sched_preempt_enable_no_resched? |
| |
On Mon, May 16, 2016 at 12:55:57PM +0200, Peter Zijlstra wrote: > You're right in that the 'proper' sequence: > > > #define preempt_enable() \ > > do { \ > > barrier(); \ > > if (unlikely(preempt_count_dec_and_test())) \ > > __preempt_schedule(); \ > > } while (0) > > > #define preempt_disable() \ > > do { \ > > preempt_count_inc(); \ > > barrier(); \ > > } while (0) > > Has a higher chance of succeeding to emit the operations to memory; but > an even smarter pants compiler might figure doing something like: > > if (preempt_count() == 1) > __preempt_schedule(); > > is equivalent and emits that instead, not bothering to modify the actual > variable at all -- the program as specified cannot tell the difference > etc..
For this to work the call __preempt_schedule() must be obfuscated though; but I think the thing we do for x86 which turns it into:
asm("call ___preempt_schedule;");
might just be enough for the compiler to get confused about that.
A normal function call would act as a compiler barrier and force the compiler to emit the memory ops.
Then again, it could maybe do:
if (preempt_count() == 1) { preempt_count_dec(); __preempt_schedule(); preempt_count_inc(); }
and think it did us a service by 'optimizing' away that memory reference in the 'fast' path.
Who knows what these compilers get up to ;-)
| |