Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp2318924imm; Thu, 21 Jun 2018 10:28:24 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJIrQqe+BdhBJOfSpPUbtTe1oCIJMYgDEJ4ODaVW0RJiu0VR6ELQU7dxtNc9t5KV9vvGeB9 X-Received: by 2002:a62:df89:: with SMTP id d9-v6mr8889741pfl.147.1529602104700; Thu, 21 Jun 2018 10:28:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529602104; cv=none; d=google.com; s=arc-20160816; b=NHJ4STBIMAab9vsSxoKR+tnruYXFBOd8DR24brHIODx/CN+lNO7VhIe3yc1L7GULK3 9iTTa0dy4cMNfAvCEkEIjJjplVMx2Wmz0LoolDLFelnN992quBkKP9zuXxTb3t2Tchkr ruzpI++2whGF7KrqxtFIOiKMHwkGUYRYmSNUDurtsBCccGRfQg9+xKMSdiITR5hFkHb8 c0aO+VE/45zw8EMy4LprfDny9LUu1WqYOs6m9i4c4oWoIh9fPw38o2s0dRzok1nYLm4p EA4M+BWlm4jMh64QQnNoBXUy+4485/2C+jPztt5UetgX5tcCkF+E39wGLsrPUBiPWVF1 XQPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:subject:cc:to :from:date:arc-authentication-results; bh=z3kWy5VURpiGnSaMnUgWHV3R6oUQ1CYqrzcXUXkUdDY=; b=PmeHgtzdbxonxNok1hUDTVnYcXu98At3yT1f8i4K/7C6F72zFzI39ZSUEGaqYU5W0d SoYmqJgnBnSTeL96zK4KowoBL2dBeL2zC4AsQULy0I72Pt8YIZN8ZEtQ1oy7e3kE0XVe Byn3klkoICafDPkUwHOJZZJHnPOkrPP0rjZj8Biqdjxk/BB2uYrWLVwnWu9UlmLvQAxZ 8sgh35Ec0HThLO6liQqt5flIriWZepdoExNd5pl6a1To8LmtlepY+GStH7KVDx4RyOup TKtFzeWbw8oXige5txBPEsZ0QmmAQnwObvygPPaJuEhTji0ovbW9l0+yzlfZXzq0teTt NCMQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r12-v6si5418100pfe.9.2018.06.21.10.28.10; Thu, 21 Jun 2018 10:28:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933146AbeFUR1O (ORCPT + 99 others); Thu, 21 Jun 2018 13:27:14 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:36822 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S932994AbeFUR1N (ORCPT ); Thu, 21 Jun 2018 13:27:13 -0400 Received: (qmail 4486 invoked by uid 2102); 21 Jun 2018 13:27:12 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 21 Jun 2018 13:27:12 -0400 Date: Thu, 21 Jun 2018 13:27:12 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: LKMM Maintainers -- Akira Yokosawa , Andrea Parri , Boqun Feng , David Howells , Jade Alglave , Luc Maranget , Nicholas Piggin , "Paul E. McKenney" , Peter Zijlstra , Will Deacon cc: Kernel development list Subject: [PATCH 2/2] tools/memory-model: Add write ordering by release-acquire and by locks Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org More than one kernel developer has expressed the opinion that the LKMM should enforce ordering of writes by release-acquire chains and by locking. In other words, given the following code: WRITE_ONCE(x, 1); spin_unlock(&s): spin_lock(&s); WRITE_ONCE(y, 1); or the following: smp_store_release(&x, 1); r1 = smp_load_acquire(&x); // r1 = 1 WRITE_ONCE(y, 1); the stores to x and y should be propagated in order to all other CPUs, even though those other CPUs might not access the lock s or be part of the release-acquire chain. In terms of the memory model, this means that rel-rf-acq-po should be part of the cumul-fence relation. All the architectures supported by the Linux kernel (including RISC-V) do behave this way, albeit for varying reasons. Therefore this patch changes the model in accordance with the developers' wishes. Signed-off-by: Alan Stern --- [as1871] tools/memory-model/Documentation/explanation.txt | 81 +++++++++++++++++++++++ tools/memory-model/linux-kernel.cat | 2 2 files changed, 82 insertions(+), 1 deletion(-) Index: usb-4.x/tools/memory-model/linux-kernel.cat =================================================================== --- usb-4.x.orig/tools/memory-model/linux-kernel.cat +++ usb-4.x/tools/memory-model/linux-kernel.cat @@ -66,7 +66,7 @@ let ppo = to-r | to-w | fence (* Propagation: Ordering from release operations and strong fences. *) let A-cumul(r) = rfe? ; r -let cumul-fence = A-cumul(strong-fence | po-rel) | wmb +let cumul-fence = A-cumul(strong-fence | po-rel) | wmb | rel-rf-acq-po let prop = (overwrite & ext)? ; cumul-fence* ; rfe? (* Index: usb-4.x/tools/memory-model/Documentation/explanation.txt =================================================================== --- usb-4.x.orig/tools/memory-model/Documentation/explanation.txt +++ usb-4.x/tools/memory-model/Documentation/explanation.txt @@ -1897,3 +1897,84 @@ non-deadlocking executions. For example Is it possible to end up with r0 = 36 at the end? The LKMM will tell you it is not, but the model won't mention that this is because P1 will self-deadlock in the executions where it stores 36 in y. + +In the LKMM, locks and release-acquire chains cause stores to +propagate in order. For example: + + int x, y, z; + + P0() + { + WRITE_ONCE(x, 1); + smp_store_release(&y, 1); + } + + P1() + { + int r1; + + r1 = smp_load_acquire(&y); + WRITE_ONCE(z, 1); + } + + P2() + { + int r2, r3, r4; + + r2 = READ_ONCE(z); + smp_rmb(); + r3 = READ_ONCE(x); + r4 = READ_ONCE(y); + } + +If r1 = 1 and r2 = 1 at the end, then both r3 and r4 must also be 1. +In other words, the smp_store_release() read by the smp_load_acquire() +together act as a sort of inter-processor fence, forcing the stores to +x and y to propagate to P2 before the store to z does, regardless of +the fact that P2 doesn't execute any release or acquire instructions. +This conclusion would hold even if P0 and P1 were on the same CPU, so +long as r1 = 1. + +We have mentioned that the LKMM treats locks as acquires and unlocks +as releases. Therefore it should not be surprising that something +analogous to this ordering also holds for locks: + + int x, y; + spinlock_t s; + + P0() + { + spin_lock(&s); + WRITE_ONCE(x, 1); + spin_unlock(&s); + } + + P1() + { + int r1; + + spin_lock(&s); + r1 = READ_ONCE(x): + WRITE_ONCE(y, 1); + spin_unlock(&s); + } + + P2() + { + int r2, r3; + + r2 = READ_ONCE(y); + smp_rmb(); + r3 = READ_ONCE(x); + } + +If r1 = 1 at the end (implying that P1's critical section executes +after P0's) and r2 = 1, then r3 must be 1; the ordering of the +critical sections forces the store to x to propagate to P2 before the +store to y does. + +In both versions of this scenario, the store-propagation ordering is +not required by the operational model. However, it does happen on all +the architectures supporting the Linux kernel, and kernel developers +seem to expect it; they have requested that this behavior be included +in the LKMM.