Received: by 2002:a25:c593:0:0:0:0:0 with SMTP id v141csp6889884ybe; Wed, 18 Sep 2019 10:41:19 -0700 (PDT) X-Google-Smtp-Source: APXvYqwW0J1XgOnyQ+CKHReweb0VOR2VcCMlxaqAco8jWnYNAbDH2RzgHu1kLjhnXPWfjFJQiSqi X-Received: by 2002:a17:906:6048:: with SMTP id p8mr10785490ejj.297.1568828479406; Wed, 18 Sep 2019 10:41:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1568828479; cv=none; d=google.com; s=arc-20160816; b=xDXL6uwwWTUiCVz4bgJ01R8Oz/ClB/44mRNqO8wOVPCTrkVTIq1EDbSpTew+aHy91+ s+Q4PRMfOgGUyBzekIZuOUXiNlhr0jGrhq+4kRdulSR0tv3C8zQcdL79bhSUWu+anyJg QdG5IIUvlXbQZt19Dbk9sIUEThHg9XN5RbgwFCUsOkvFQWwwUb7u8MfvzgQeDCn4W47x rQMglv6apZ2dWFMKgV63kldq8EKTmnmaWDmPttd1rv4IKta65v2B+3G5176H1VUCTXuR IhECVMM6Gou9afQmz4xHZyOzoTTmfwvi152l5NS2RL1Q6ndx3VF/Jm4EpIct2TJTVOxR dIcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=86ZUn97/3KZwNNgVgFqkj5nnsJKKhe/XOuAYAPGVnyg=; b=Y402pnVvqiq8Q6fe+5WgHcmtK1bNwPfvTOCa2LA0fL3wposhzntOUKYAFQXHrdJd5Z CNy+auQF2LPJzZxVZfw+p5Ny5G9Qpcbf3+ON18zDGIYUlbIlzM2Xa+hJjvcw5WTddKig SvaXCdiEo8IkBiIN+RneOuhbqBEYVX2EC1Ej9DPg9m4A8ZLLJFJrb1ihFw+ueOyZpDbY uyIaoHphx4dGPjjxqW/+MPWw6vUYrU03pfbQ65xCrUgPQmRZ0rurdm7akWw59ftgg5sd ouTURc+H9d2QUZOkqKOS5+GhI/483aT+OGTJ67cMYrHxTF2D825R5I506mKTQu/sphBV VUWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux-foundation.org header.s=google header.b=CyLWlrJo; 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 s18si3225085ejb.49.2019.09.18.10.40.55; Wed, 18 Sep 2019 10:41:19 -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; dkim=pass header.i=@linux-foundation.org header.s=google header.b=CyLWlrJo; 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 S2387769AbfIRQs6 (ORCPT + 99 others); Wed, 18 Sep 2019 12:48:58 -0400 Received: from mail-lj1-f182.google.com ([209.85.208.182]:36791 "EHLO mail-lj1-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387733AbfIRQs5 (ORCPT ); Wed, 18 Sep 2019 12:48:57 -0400 Received: by mail-lj1-f182.google.com with SMTP id v24so647014ljj.3 for ; Wed, 18 Sep 2019 09:48:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=86ZUn97/3KZwNNgVgFqkj5nnsJKKhe/XOuAYAPGVnyg=; b=CyLWlrJoS3bO7FoH77HyM4XEqzmX9zqgMXKEBMrGTDXCSDubDkAV6dEVe9f+9NU6ps TjIQho7CvgDPZyQ2qs0MfWbp+zWKGSXvdZ4IBJgiegj5BiaixElPEV/qUQVMRqfs505T j+1vHPZbB2Dvu8j2pvIkSc4y42bGPAM9/jxKQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=86ZUn97/3KZwNNgVgFqkj5nnsJKKhe/XOuAYAPGVnyg=; b=Plxylyw7mUqorXBXZ+W3oHEWRixaTPNOM8B4Y5ZDpKwH5XJa5NlB6xQdHh20AeVqSt nJ4xKrlvaZHVF5Jiw8/8NGH2FONjAkpBZdxWM+w1RgKztwmsN+CfUvR+XFPJUmLaCPGI 1vqmPwYwWF0Zx79cHYqIBV89H/2Wl+AtJnzUtt3awhN00tNgp+Ctlm5ISjO3+jwuLLAR 41fzdL50xmUeiClte/HLxM3RYHn9qLNnK/nQU8xPX8vnI7ISe7o7Zq16XxMuKesQNCHV g3p0sIhP8WqsHEBZX6/Mp4O+QiB9MaC0C+t6MDeHKdxVEqRlqLr9TQKMU1h+2Mp0K30c 5UOA== X-Gm-Message-State: APjAAAXC/rWqcM+uy4YuaHI9wZGu0RAVkKWIt0cfV8FKJSwvo7fgCeFY N/UD4YGudKuwwRI5eyfBdM24AIZjeg0= X-Received: by 2002:a2e:9ad6:: with SMTP id p22mr2826056ljj.168.1568825335235; Wed, 18 Sep 2019 09:48:55 -0700 (PDT) Received: from mail-lj1-f181.google.com (mail-lj1-f181.google.com. [209.85.208.181]) by smtp.gmail.com with ESMTPSA id l5sm1077356lfk.17.2019.09.18.09.48.53 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 18 Sep 2019 09:48:54 -0700 (PDT) Received: by mail-lj1-f181.google.com with SMTP id l21so640831lje.4 for ; Wed, 18 Sep 2019 09:48:53 -0700 (PDT) X-Received: by 2002:a2e:8789:: with SMTP id n9mr2848073lji.52.1568825333672; Wed, 18 Sep 2019 09:48:53 -0700 (PDT) MIME-Version: 1.0 References: <20190915145905.hd5xkc7uzulqhtzr@willie-the-truck> <25289.1568379639@warthog.procyon.org.uk> <28447.1568728295@warthog.procyon.org.uk> <20190917170716.ud457wladfhhjd6h@willie-the-truck> <15228.1568821380@warthog.procyon.org.uk> In-Reply-To: <15228.1568821380@warthog.procyon.org.uk> From: Linus Torvalds Date: Wed, 18 Sep 2019 09:48:37 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: Do we need to correct barriering in circular-buffers.rst? To: David Howells Cc: Will Deacon , "Paul E. McKenney" , Mark Rutland , Linux List Kernel Mailing , linux-fsdevel , Peter Zijlstra Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Sep 18, 2019 at 8:43 AM David Howells wrote: > > It mandates using smp_store_release() to update buffer->head in the producer > and buffer->tail in the consumer - but these need pairing with memory barriers > used when reading buffer->head and buffer->tail on the other side. No, the rule with smp_store_release() should be that it's paired with "smp_load_acquire()". No other barriers needed. If you do that thread #1 thread #2 ... add data to queue .. smp_store_release(x) smp_load_acquire(x) ... read data from queue .. then you should need no other barriers. But yes, store_release(x) should always pair with the load_acquire(x), and the guarantee is that if the load_acquire reads the value that the store_release stored, then all subsequent reads in thread #2 will see all preceding writes in thread #1. That's the optimal locking for a simple queue with a reader and a writer and no other locking needed between the two. HOWEVER. I think this is all entirely pointless wrt the pipe buffer use. You don't have a simple queue. You have multiple writers, and you have multiple readers. As a result, you need real locking. So don't do the barriers. If you do the barriers, you're almost certainly doing something buggy. You don't have the simple "consumer -> producer" thing. Or rather, you don't _only_ have that thing. A reader "produces" a new tail as far as the writer is concerned (so the reader that has consumed an entry does a smp_store_release(tail) -> smp_load_acquire(tail) on the writer side when the writer looks for a new entry it can fill). BUT! A writer also needs to make sure it's the *only* writer for that new entry, and similarly a reader that is about to consume an entry needs to make sure it's the only reader of that entry. So it is *not* that kind of simple hand-off situation at all. End result: use a lock. Seriously. Anything else is going to be buggy, or going to be incredibly subtle. Don't do those barriers. They are wrong. Barriers simply do not protect against two concurrent readers, or two concurrent writers. Barriers are useless. Now, it's possible that barriers together with very clever atomics could do a lockless model, but then all the cleverness is going to be in the lockless part of the code, not the barriers. So even if we eventually do a lockless model, it's completely wrong to do the barriers first. And no, lockless isn't as simple as "readers can do a atomic_add_return_relaxed() to consume an entry, and writers can do a atomic_cmpxchg() to produce one". I think the only possible lockless model is that readers have some exclusion against other readers (so now you have only one reader at a time), and then you fundamentally know that a reader can update the tail pointer without worrying about any races (because a reader will never race against another reader, and a writer will only ever _read_ the tail pointer). So then - once you have reader-reader exclusion, the _tail_ update is simple: smp_store_release(old_tail+1, &tail); because while there are multiple writers, the reader doesn't care (the above, btw, assumes that head/tail themselves aren't doing the "& bufsize" thing, and that that is done at use time - that also makes it easy to see the difference between empty and full). But this still requires that lock around all readers. And we have that: the pipe mutex. But writers have the same issue, and we don't want to use the pipe mutex for writer exclusion, since we want to allow atomic writers. So writers do have to have a lock, or they need to do something clever with a reservation system that uses cmpxchg. Honestly, just do the lock. The way this should be done: 1) do the head/tail conversion using the EXISTING locking. We have the pipe_mutex, and it serializes everybody right now, and it makes any barriers or atomics pointless. Just covert to a sane and simple head/tail model. NO BARRIERS! *after* you've done this, do the next phase: 2) convert the writers to use an irq-safe spinlock, and either make the readers look at it too, or do the above smp_store_release() for the final tail update (and the writers need to use a smp_load_acquire() to look at the tail, despite their lock). NO BARRIERS (well, outside the tail thing above). and *after* you've done #2, you can now do writes from atomic context. At that point you are done. Consider youself happy, but also allow for the possibility that some day you'll see lock contention with lots of writers, and that *maybe* some day (unlikely) you'd want to look at doing 3) see if you can make the writers do some clever lockless reservation model. But that #3 really should be considered a "we are pretty sure it's possible in theory, but it's questinably useful, and hopefully we'll never even need to consider it". Linus