Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp2175229pxb; Fri, 24 Sep 2021 23:26:30 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzl1vZ/+Io2gsEKukTZnOHjHHphK9CC4Pc1f/ZrczscgrUX9as5kEOiG+/0CQLwDhee3v4r X-Received: by 2002:a50:9d02:: with SMTP id v2mr9729964ede.105.1632551190584; Fri, 24 Sep 2021 23:26:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632551190; cv=none; d=google.com; s=arc-20160816; b=g6QxZ7IED/m5DtbNWb1qkuxzpkiZ1xUax+Ge9r99/OpAbrUQgbgtggkuac/EU8Y2Ko 1J7bXqzYuU1lx4lB9Co0IJs1+kFFmMIZQWHXor7q8NQBkHaNVdOaoGf57nSTVlvtIpmc rF5SBlN8fNJ4U6OOtA2YYIjUM9L6E1FAHJUJNmL9LhD4jQNYrivR6QiaU9WKccBZLsVJ zv00X1mt/KrJWy3PVblEWaaICWfFFKTvj7cLDG7LuLDoZAbArD6VFFX+D3cRUR9jp++B pTjcdxCoAYsK/QCDAFFPAJZpk9AxZJvOfe7l2UgFQQWS4L2Y1ny7o7EsE9ThN8aQ36XC xZmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:thread-index:thread-topic :content-transfer-encoding:mime-version:subject:references :in-reply-to:message-id:cc:to:from:date:dkim-signature:dkim-filter; bh=YOIiaTIjSWSIDVY7x919ScLocg4hGeXlWAaaAgSsT3g=; b=P4YScExyh9DINSVJ8PsPlDzRDEKpmSM5fQldigFVzoopIvy4Xc3+14ukdmcxOb0FRa 4IiT3GqU1Fkvv06+DKmB1DPUXIF7KzGI+IDaaEFWTiFd0S5seajrPxi0PTSOXY0gMT4p ajB7leisZiXam4wZvc8asFWz97F0vPqDBAghSjqDnnDF1P89N7bl8u098D7Vl6vrLAYM 22psqYHEDtw8VYMJwto8wIom2QxwfCj7pGL9ZILH3lPr5zWRl9k5yubrJrZCAzs3bIOq 7MsF4cupGN5QCJGm8SHLsmhyfacjgtmIhFIRbBuDFLLj0FNIMT2JHHUX8px0GeLJuFuF 16HA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@efficios.com header.s=default header.b=EcWiwkWH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g15si10885135edf.622.2021.09.24.23.26.06; Fri, 24 Sep 2021 23:26:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@efficios.com header.s=default header.b=EcWiwkWH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=efficios.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348408AbhIXUYO (ORCPT + 99 others); Fri, 24 Sep 2021 16:24:14 -0400 Received: from mail.efficios.com ([167.114.26.124]:56612 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348406AbhIXUYL (ORCPT ); Fri, 24 Sep 2021 16:24:11 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id 4F88B32A286; Fri, 24 Sep 2021 16:22:37 -0400 (EDT) Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id ubnydGavbSbG; Fri, 24 Sep 2021 16:22:36 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.efficios.com (Postfix) with ESMTP id 9519632A046; Fri, 24 Sep 2021 16:22:36 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.efficios.com 9519632A046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=efficios.com; s=default; t=1632514956; bh=YOIiaTIjSWSIDVY7x919ScLocg4hGeXlWAaaAgSsT3g=; h=Date:From:To:Message-ID:MIME-Version; b=EcWiwkWHgCbolkPK54UoSOGHyBh7sLnqQysFiJ6LBzQqRavhhHJEFqSHcv6uz7Q7D eAs2k9d5EKD3DPviyLjnW3+3SRYGZZ+yXFMGyGOQRNEzuJlM+EMy/KS+qGIjVOBSbe ourNAhWdTdzxTLT6RhoCDtrTnf42fvy8oIVOLcc3+OLQVuDTi1qLAawaxDehGXjNEJ zR0WxyEA4dPzKj2Znh6Nx841pM4iNBXk4IRbRFkQNJCdqwBNC9ajNV8DNipmpw2OLU DS3yRuh1fGM9rwl0Z/QGb4+RNq/glWZwWXXa2NWleakxIIPNSYY4GGdiyFjWFcVht6 aqkXxS6x+fLDQ== X-Virus-Scanned: amavisd-new at efficios.com Received: from mail.efficios.com ([127.0.0.1]) by localhost (mail03.efficios.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 6uiIKt2BVKzp; Fri, 24 Sep 2021 16:22:36 -0400 (EDT) Received: from mail03.efficios.com (mail03.efficios.com [167.114.26.124]) by mail.efficios.com (Postfix) with ESMTP id 7FB4032A30A; Fri, 24 Sep 2021 16:22:36 -0400 (EDT) Date: Fri, 24 Sep 2021 16:22:36 -0400 (EDT) From: Mathieu Desnoyers To: Alan Stern Cc: Peter Zijlstra , Linus Torvalds , Will Deacon , paulmck , Andrea Parri , Boqun Feng , Nicholas Piggin , David Howells , j alglave , luc maranget , akiyks@gmail.com, linux-kernel , linux-toolchains , linux-arch Message-ID: <1103437077.37428.1632514956401.JavaMail.zimbra@efficios.com> In-Reply-To: <20210924195223.GA287835@rowland.harvard.edu> References: <20210924183858.GA25901@localhost> <20210924195223.GA287835@rowland.harvard.edu> Subject: Re: [RFC] LKMM: Add volatile_if() MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [167.114.26.124] X-Mailer: Zimbra 8.8.15_GA_4125 (ZimbraWebClient - FF92 (Linux)/8.8.15_GA_4059) Thread-Topic: LKMM: Add volatile_if() Thread-Index: gKJxIHbLtmSI3npLIydDVLk94GMdmg== Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org ----- On Sep 24, 2021, at 3:52 PM, Alan Stern stern@rowland.harvard.edu wrote: > On Fri, Sep 24, 2021 at 02:38:58PM -0400, Mathieu Desnoyers wrote: >> Hi, >> >> Following the LPC2021 BoF about control dependency, I re-read the kernel >> documentation about control dependency, and ended up thinking that what >> we have now is utterly fragile. >> >> Considering that the goal here is to prevent the compiler from being able to >> optimize a conditional branch into something which lacks the control >> dependency, while letting the compiler choose the best conditional >> branch in each case, how about the following approach ? >> >> #define ctrl_dep_eval(x) ({ BUILD_BUG_ON(__builtin_constant_p((_Bool) >> x)); x; }) >> #define ctrl_dep_emit_loop(x) ({ __label__ l_dummy; l_dummy: asm volatile goto >> ("" : : : "cc", "memory" : l_dummy); (x); }) >> #define ctrl_dep_if(x) if ((ctrl_dep_eval(x) && ctrl_dep_emit_loop(1)) >> || ctrl_dep_emit_loop(0)) >> >> The idea is to forbid the compiler from considering the two branches as >> identical by adding a dummy loop in each branch with an empty asm goto. >> Considering that the compiler should not assume anything about the >> contents of the asm goto (it's been designed so the generated assembly >> can be modified at runtime), then the compiler can hardly know whether >> each branch will trigger an infinite loop or not, which should prevent >> unwanted optimisations. >> >> With this approach, the following code now keeps the control dependency: >> >> z = READ_ONCE(var1); >> ctrl_dep_if (z) >> WRITE_ONCE(var2, 5); >> else >> WRITE_ONCE(var2, 5); >> >> And the ctrl_dep_eval() checking the constant triggers a build error >> for: >> >> y = READ_ONCE(var1); >> ctrl_dep_if (y % 1) >> WRITE_ONCE(var2, 5); >> else >> WRITE_ONCE(var2, 6); >> >> Which is good to have to ensure the compiler don't end up removing the >> conditional branch because the resulting evaluation ends up evaluating a >> constant. >> >> Thoughts ? > > As I remember the earlier discussion, Linus felt that the kernel doesn't > really need any sort of explicit control dependency (although we called > it "volatile if"). In many cases there is an actual semantic > dependency, so it doesn't matter what the compiler does -- the hardware > will enforce the actual dependency. In other cases, we can work around > the issue by using acquire loads or release stores. IMHO, having to chase down what the instruction selection does on every architecture for every supported compiler for each control dependency in order to confirm that the control dependency is still present in the resulting assembly is fragile. If the kernel really doesn't need explicit control dependency, then maybe the whole notion of "control dependency"-based ordering should be removed in favor of explicit acquire loads/release stores and barriers. > In fact, Linus's biggest wish was to have a weak form of compiler > barrier, one which would block the compiler from reordering accesses > across the barrier but wouldn't invalidate the compiler's knowledge > about the values of earlier reads (which barrier() would do). Then maybe we could simply tweak the ctrl_dep_emit_loop() implementation and remove the "memory" clobber. Then its only effect is to prevent the compiler from knowing whether there is an infinite loop, thus preventing reordering accesses across the conditional branch without requiring the compiler to discard earlier reads: #define ctrl_dep_emit_loop(x) ({ __label__ l_dummy; l_dummy: asm_volatile_goto ("" : : : : l_dummy); (x); }) and for the records, the ctrl_dep_eval(x) implementation needs extra parentheses: #define ctrl_dep_eval(x) ({ BUILD_BUG_ON(__builtin_constant_p((_Bool) (x))); (x); }) Thanks, Mathieu -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com