From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61CA6C47423 for ; Thu, 1 Oct 2020 19:30:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 13006206C9 for ; Thu, 1 Oct 2020 19:30:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730147AbgJATaQ (ORCPT ); Thu, 1 Oct 2020 15:30:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729993AbgJATaP (ORCPT ); Thu, 1 Oct 2020 15:30:15 -0400 Received: from ZenIV.linux.org.uk (zeniv.linux.org.uk [IPv6:2002:c35c:fd02::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F334FC0613D0; Thu, 1 Oct 2020 12:30:14 -0700 (PDT) Received: from viro by ZenIV.linux.org.uk with local (Exim 4.92.3 #3 (Red Hat Linux)) id 1kO4H8-00A0dq-BS; Thu, 01 Oct 2020 19:29:58 +0000 Date: Thu, 1 Oct 2020 20:29:58 +0100 From: Al Viro To: Alan Stern Cc: "Paul E. McKenney" , parri.andrea@gmail.com, will@kernel.org, peterz@infradead.org, boqun.feng@gmail.com, npiggin@gmail.com, dhowells@redhat.com, j.alglave@ucl.ac.uk, luc.maranget@inria.fr, akiyks@gmail.com, dlustig@nvidia.com, joel@joelfernandes.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org Subject: Re: Litmus test for question from Al Viro Message-ID: <20201001192958.GH3421308@ZenIV.linux.org.uk> References: <20201001045116.GA5014@paulmck-ThinkPad-P72> <20201001161529.GA251468@rowland.harvard.edu> <20201001163646.GG3421308@ZenIV.linux.org.uk> <20201001183925.GA259470@rowland.harvard.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201001183925.GA259470@rowland.harvard.edu> Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Oct 01, 2020 at 02:39:25PM -0400, Alan Stern wrote: > The problem with a plain write is that it isn't guaranteed to be atomic > in any sense. In principle, the compiler could generate code for CPU1 > which would write 0 to V->A more than once. > > Although I strongly doubt that any real compiler would actually do this, > the memory model does allow for it, out of an overabundance of caution. Point... OK, not a problem - actually there will be WRITE_ONCE() for other reasons; the real-life (pseudo-)code is spin_lock(&file->f_lock); to_free = NULL; head = file->f_ep; if (head->first == &epitem->fllink && epitem->fllink.next == NULL) { /* the set will go empty */ file->f_ep = NULL; if (!is_file_epoll(file)) { /* * not embedded into struct eventpoll; we want it * freed unless it's on the check list, in which * case we leave it for reverse path check to free. */ v = container_of(head, struct ep_head, epitems); if (!smp_load_acquire(&v->next)) to_free = v; } } hlist_del_rcu(&epitem->fllink); spin_unlock(file->f_lock); kfree(to_free); and hlist_del_rcu() will use WRITE_ONCE() to store the updated forward links. That goes into ep_remove() and CPU1 side of that thing is the final (set-emptying) call. CPU2 side is the list traversal step in reverse_path_check() and in clear_tfile_check_list(): // under rcu_read_lock() to_free = head; epitem = rcu_dereference(hlist_first_rcu(&head->epitems)); if (epitem) { spin_lock(&epitem->file->f_lock); if (!hlist_empty(&head->epitems)) to_free = NULL; head->next = NULL; spin_unlock(&epitem->file->f_lock); } kfree(to_free);