Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp4306879rwb; Tue, 8 Nov 2022 15:20:24 -0800 (PST) X-Google-Smtp-Source: AMsMyM7fn0ob5LEjlHCelZ0lUTL1YMGFau/Xd7UgcO3Rr3QfSZtpHV0vFPQig9MYvknZ2znA0WBK X-Received: by 2002:a05:6402:4445:b0:461:b506:de51 with SMTP id o5-20020a056402444500b00461b506de51mr26764058edb.388.1667949624359; Tue, 08 Nov 2022 15:20:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1667949624; cv=none; d=google.com; s=arc-20160816; b=uT/t0BV5Ix2jPWdO8UFOQhKCO2Km/BdSxhzCuubh7U3IMYAodGn/LyygpUL2aiHB1K dCkWRM6lQ7qXsxLuLBcTLc2vexHvz+9h/wWOjvrLBB77WQpKcf6riRLtnuN+dnPKVyAF GGU3DZLcMiVRiotW6MHLJI2zcPDjDAMVOKOf8J4cgYJE/FhtbiyCK4iG5yvwqtaW4meS F6KtvIWPHL2mM9+a3ELtHJuygq6ldLH0kZbDBHgbU6V65Cq1m4SE4AwC2RrMe3vRQo0h boD7zk1os/t3mTuGr3Fx4MMeBFOyUamdIDDnkhV4RMwFSMlo1U0ElJWZtoc7zOWAlrd/ ik2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:references :cc:to:from:content-language:subject:user-agent:mime-version:date :message-id:dkim-signature; bh=Ltmgz4FRGZvYJ6x9NIHhx3nQQsP+YYpgZpdkS9JvU+o=; b=KrefLpDGh+H239VmOuR1krrYXbGqyER9Ew2EQ4NcBTC5VWJ9y5QXgriK1SxCIkafMs 856k7SD/OOAPmLMy95y+Vx4MU8WB9BtQ1fdM1uqOgg7sqt5siCLtZSQU0ftbDOpK38uu i8S1fk4A9gNo3L7dcC5qOLulsFikTHjXI/7AXvNS4QykdRKKGPLHYfRQUcnPUQqESHli rJDf6r2ZmqsZ76i3lxRM8u2Oqqo9aWqQD/H582ndSbnRjBx5ZrdV9h9USUo0L4gnSE5Q L/ENTwLK3kXSFIO+aKPxEBWbRrqqO6QI/zLy4XR+Gw7NTYa+ZJyP700Yl0TvjYmyx3xj Dl3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cybernetics.com header.s=mail header.b=CYxZCfWI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cybernetics.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ht16-20020a170907609000b0078d805901b1si16615154ejc.489.2022.11.08.15.20.01; Tue, 08 Nov 2022 15:20:24 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@cybernetics.com header.s=mail header.b=CYxZCfWI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cybernetics.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229545AbiKHXHp (ORCPT + 93 others); Tue, 8 Nov 2022 18:07:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229552AbiKHXHm (ORCPT ); Tue, 8 Nov 2022 18:07:42 -0500 Received: from mail.cybernetics.com (mail.cybernetics.com [173.71.130.66]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D50A06316A for ; Tue, 8 Nov 2022 15:07:41 -0800 (PST) X-ASG-Debug-ID: 1667948858-1cf43916953bcb50002-xx1T2L Received: from cybernetics.com ([10.10.4.126]) by mail.cybernetics.com with ESMTP id lYGEv62L2AfLvHwX; Tue, 08 Nov 2022 18:07:38 -0500 (EST) X-Barracuda-Envelope-From: tonyb@cybernetics.com X-ASG-Whitelist: Client DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=cybernetics.com; s=mail; bh=Ltmgz4FRGZvYJ6x9NIHhx3nQQsP+YYpgZpdkS9JvU+o=; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:References:Cc:To:From: Content-Language:Subject:MIME-Version:Date:Message-ID; b=CYxZCfWI9CbLN1OQJ+F/ lwI/60xTPhKB9vLfRVxOtlpVip1ZX818BGZVCOx0M+/d5dhtONKggrqo35EvYWpK5LeWR7KCcNYK9 Uu39J11IXKaGtG99iwsRZLDHr6rCR/gtHmFLTeclZXqUP9XdBDY2UEuE/CpD6ceXZSW1OGYti0= Received: from [10.157.2.224] (HELO [192.168.200.1]) by cybernetics.com (CommuniGate Pro SMTP 7.1.1) with ESMTPS id 12318971; Tue, 08 Nov 2022 18:07:38 -0500 Message-ID: Date: Tue, 8 Nov 2022 18:07:37 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2 Subject: Re: io_ordering.rst vs. memory-barriers.txt Content-Language: en-US X-ASG-Orig-Subj: Re: io_ordering.rst vs. memory-barriers.txt From: Tony Battersby To: Will Deacon , Jonathan Corbet Cc: Alan Stern , Andrea Parri , Peter Zijlstra , Boqun Feng , Nicholas Piggin , David Howells , Jade Alglave , Luc Maranget , "Paul E. McKenney" , Akira Yokosawa , Daniel Lustig , Joel Fernandes , "linux-kernel@vger.kernel.org" , linux-arch@vger.kernel.org References: <1924eda8-aea6-da64-04a7-35f3327a7f4f@cybernetics.com> In-Reply-To: <1924eda8-aea6-da64-04a7-35f3327a7f4f@cybernetics.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: UNKNOWN[10.10.4.126] X-Barracuda-Start-Time: 1667948858 X-Barracuda-URL: https://10.10.4.122:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at cybernetics.com X-Barracuda-Scan-Msg-Size: 4231 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org (resending in plaintext; damn Thunderbird upgrades...) While looking up documentation for PCI write posting I noticed that the example in Documentation/driver-api/io_ordering.rst seems to contradict Documentation/memory-barriers.txt: ----------- Documentation/driver-api/io_ordering.rst: On some platforms, so-called memory-mapped I/O is weakly ordered. On such platforms, driver writers are responsible for ensuring that I/O writes to memory-mapped addresses on their device arrive in the order intended. This is typically done by reading a 'safe' device or bridge register, causing the I/O chipset to flush pending writes to the device before any reads are posted. A driver would usually use this technique immediately prior to the exit of a critical section of code protected by spinlocks. This would ensure that subsequent writes to I/O space arrived only after all prior writes (much like a memory barrier op, mb(), only with respect to I/O). A more concrete example from a hypothetical device driver:: ... CPU A: spin_lock_irqsave(&dev_lock, flags) CPU A: val = readl(my_status); CPU A: ... CPU A: writel(newval, ring_ptr); CPU A: spin_unlock_irqrestore(&dev_lock, flags) ... CPU B: spin_lock_irqsave(&dev_lock, flags) CPU B: val = readl(my_status); CPU B: ... CPU B: writel(newval2, ring_ptr); CPU B: spin_unlock_irqrestore(&dev_lock, flags) ... In the case above, the device may receive newval2 before it receives newval, which could cause problems. Fixing it is easy enough though:: ... CPU A: spin_lock_irqsave(&dev_lock, flags) CPU A: val = readl(my_status); CPU A: ... CPU A: writel(newval, ring_ptr); CPU A: (void)readl(safe_register); /* maybe a config register? */ CPU A: spin_unlock_irqrestore(&dev_lock, flags) ... CPU B: spin_lock_irqsave(&dev_lock, flags) CPU B: val = readl(my_status); CPU B: ... CPU B: writel(newval2, ring_ptr); CPU B: (void)readl(safe_register); /* maybe a config register? */ CPU B: spin_unlock_irqrestore(&dev_lock, flags) Here, the reads from safe_register will cause the I/O chipset to flush any pending writes before actually posting the read to the chipset, preventing possible data corruption. ----------- Documentation/memory-barriers.txt: ========================== KERNEL I/O BARRIER EFFECTS ========================== Interfacing with peripherals via I/O accesses is deeply architecture and device specific. Therefore, drivers which are inherently non-portable may rely on specific behaviours of their target systems in order to achieve synchronization in the most lightweight manner possible. For drivers intending to be portable between multiple architectures and bus implementations, the kernel offers a series of accessor functions that provide various degrees of ordering guarantees: (*) readX(), writeX(): The readX() and writeX() MMIO accessors take a pointer to the peripheral being accessed as an __iomem * parameter. For pointers mapped with the default I/O attributes (e.g. those returned by ioremap()), the ordering guarantees are as follows: 1. All readX() and writeX() accesses to the same peripheral are ordered with respect to each other. This ensures that MMIO register accesses by the same CPU thread to a particular device will arrive in program order. 2. A writeX() issued by a CPU thread holding a spinlock is ordered before a writeX() to the same peripheral from another CPU thread issued after a later acquisition of the same spinlock. This ensures that MMIO register writes to a particular device issued while holding a spinlock will arrive in an order consistent with acquisitions of the lock. ----------- To summarize: io_ordering.rst says to use readX() before spin_unlock to order writeX() calls (on some platforms). memory-barriers.txt says writeX() calls are already ordered when holding the same spinlock. So...which one is correct? There is another example of flushing posted PCI writes at the bottom of Documentation/PCI/pci.rst, but that one is consistent with memory-barriers.txt. Tony Battersby Cybernetics