From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753734AbcEPLBA (ORCPT ); Mon, 16 May 2016 07:01:00 -0400 Received: from merlin.infradead.org ([205.233.59.134]:35638 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753503AbcEPLA6 (ORCPT ); Mon, 16 May 2016 07:00:58 -0400 Date: Mon, 16 May 2016 13:00:54 +0200 From: Peter Zijlstra To: Thomas Gleixner Cc: Vikram Mulukutla , linux-kernel@vger.kernel.org Subject: Re: Additional compiler barrier required in sched_preempt_enable_no_resched? Message-ID: <20160516110054.GG3205@twins.programming.kicks-ass.net> References: <573576B3.50908@codeaurora.org> <20160513145814.GS3192@twins.programming.kicks-ass.net> <573658D1.2080601@codeaurora.org> <20160516105557.GL3193@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160516105557.GL3193@twins.programming.kicks-ass.net> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 ;-)