Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp1070711pxj; Sat, 15 May 2021 02:57:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz7gXHMpFOwOp9G5lqLy3nx35mc/pFiYvTcJ82Iq1oyfoPwCWsZjqKfcOZwtZ5CfTu/0z0k X-Received: by 2002:aa7:c349:: with SMTP id j9mr59186179edr.230.1621072679675; Sat, 15 May 2021 02:57:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621072679; cv=none; d=google.com; s=arc-20160816; b=RS84wjiOBR9yR/c5YnbH1d4ZLLgxcplgg29LyVa1EwUyOE6JQxUJ9c6B4GBhuPyPf5 gOpIcfuPw15LyFVBZY7oMlwt6tHnymwaaApMtRo0TCCVISdxAMomF5ZYnqg3MFSNaDO3 vZ5DK1rsYdv/W3h9XsIEf8j+QiI7MzBu0jR2qG+nvTtaFO1Wh3TA16Aj6o7qzaunCBUi cZJcODugbx4Zb9e3yCGKjDzmYOHRowefmDbGNcqiTWOQaEJequSkMdO4+ioghgQImYUu qFak/WEYLx+ugZ8NZvzBdVGNRvpuXqveV5g+IV6bdWPt761xKkefRBJJCJT6kQar3exE TRdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=NjtwKv6NrB8SPBuVpG36NFqEZWmMmxmKo2gvkaudcBo=; b=bujQzoPznIt8wYI0MPuH2eDrElPukguqurmwuORWrf3YRAwoyMlolQQnoH6Wn+D0Zk 4KGSxXSCXzL/V9W8HJBCfWG3r7kR4JLwcbBb8tyIO23LIDClBY0aQ250jUPzo7e4eHa5 DV3hIGTVuV3UrETYo8cWlGo1Zmsyr/9RvJQqKGlNftlBNAaYuEBzlUyiLv3ILzzeZAoH 7bcc/IShBooztPqC3NMw+jtX8wvqM6ZxpHSzh0F5qX0SP0/VnW1U0d/4weVOGm58+8av z+H5ZxbzLYVSkW49rOjwxQMB6lIwq9DDXlhqJC+aU2lo8VxVf9hM3oIcSCLfct8r3EJj vTKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=l7LqZu1J; 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=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id k25si1276929ejr.183.2021.05.15.02.57.12; Sat, 15 May 2021 02:57:59 -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=@kernel.org header.s=k20201202 header.b=l7LqZu1J; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231479AbhENVCH (ORCPT + 99 others); Fri, 14 May 2021 17:02:07 -0400 Received: from mail.kernel.org ([198.145.29.99]:44312 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231476AbhENVBk (ORCPT ); Fri, 14 May 2021 17:01:40 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 925CB613EB; Fri, 14 May 2021 21:00:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1621026027; bh=EJSSCj8OOVI3N65uFjlEgbTTHDyMjowlET81oNMQdRU=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=l7LqZu1JIys3LK0PBkqOenWYaEK3ySNAQurzGAG5Wy3QkoiqFqQA4DMT8AUsK9m+p MoTYmE1XutoMc46hqGR0LmieHX96F1noR7MkO4YRGFQBBk4jsl/tEDd+vCW4+Qamod 5Mf/HUie27GOYbrJ/oSkOWzUh/WMrnlZ+nXOPsXBQubK0IZU5/BeV/CQ1Z/LIj3rev hGTRhn2jBeNF2bh9MnqD+e8B1FZViz7iR5Qrb1TM+VPiv1lXKZ8mctUcWc/DwqSCrv StpHOEDtPWdck+KE7TTnaAveaQFnGYfu5I+5V/Zyvfr6/U/0lr1PHG5yosbtMc+hZB yodPq6U+Mo83g== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 5C96E5C02A5; Fri, 14 May 2021 14:00:27 -0700 (PDT) Date: Fri, 14 May 2021 14:00:27 -0700 From: "Paul E. McKenney" To: Manfred Spraul Cc: LKML , Davidlohr Bueso , Andrew Morton , 1vier1@web.de Subject: Re: [PATCH] ipc/sem.c: use READ_ONCE()/WRITE_ONCE() for use_global_lock Message-ID: <20210514210027.GP975577@paulmck-ThinkPad-P17-Gen-1> Reply-To: paulmck@kernel.org References: <20210514175319.12195-1-manfred@colorfullife.com> <20210514194407.GN975577@paulmck-ThinkPad-P17-Gen-1> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, May 14, 2021 at 10:25:17PM +0200, Manfred Spraul wrote: > Hi Paul, > > On 5/14/21 9:44 PM, Paul E. McKenney wrote: > > On Fri, May 14, 2021 at 07:53:19PM +0200, Manfred Spraul wrote: > > > The patch solves two weaknesses in ipc/sem.c: > > > > > > 1) The initial read of use_global_lock in sem_lock() is an > > > intentional race. KCSAN detects these accesses and prints > > > a warning. > > > > > > 2) The code assumes that plain C read/writes are not > > > mangled by the CPU or the compiler. > > > > > > To solve both issues, use READ_ONCE()/WRITE_ONCE(). > > > Plain C reads are used in code that owns sma->sem_perm.lock. > > > > > > Signed-off-by: Manfred Spraul > > Reviewed-by: Paul E. McKenney > > > > One follow-up question: If I am reading the code correctly, there is > > a call to complexmode_enter() from sysvipc_sem_proc_show() that does > > not hold the global lock. Does this mean that the first check of > > ->use_global_lock in complexmode_enter() should be marked? > > Now you made me nervous, usually I do not test the proc interface. > According to the documentation in sysvipc_sem_proc_show(), > sysvipc_find_ipc() acquires the global lock. "It is a service that I provide." ;-) > > ??????? /* > > ???????? * The proc interface isn't aware of sem_lock(), it calls > > ???????? * ipc_lock_object() directly (in sysvipc_find_ipc). > > ???????? * In order to stay compatible with sem_lock(), we must > > ???????? * enter / leave complex_mode. > > ???????? */ > I have just tested it again: Yes, this is still true. OK, so the sequence of events is as follow? o sysvipc_proc_start() is invoked to start, as the name implies. o sysvipc_proc_start() invokes sysvipc_find_ipc(), which scans the IDs and invokes ipc_lock_object() on the one at pos. o ipc_lock_object() acquires the corresponding lock, which seems unlikely to be sem_perm.lock, though I freely admit that I do not know this code very well. Ah, I see it now. The kernel_ipc_perm that sysvipc_find_ipc is looking at is the first member of the sem_array structure, and that member is named sem_perm. > Perhaps, as future improvement: The rest of ipc/sem.c speaks about > "sem_perm.lock", and here we suddenly use a function name instead of the > structure member name. > > > "it calls ipc_lock_object() (i.e.: spin_lock(&sma->sem_perm.lock)). As usual, it seems obvious once you know the trick. ;-) Thanx, Paul > > > --- > > > ipc/sem.c | 11 +++++++---- > > > 1 file changed, 7 insertions(+), 4 deletions(-) > > > > > > diff --git a/ipc/sem.c b/ipc/sem.c > > > index bf534c74293e..a0ad3a3edde2 100644 > > > --- a/ipc/sem.c > > > +++ b/ipc/sem.c > > > @@ -217,6 +217,8 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it); > > > * this smp_load_acquire(), this is guaranteed because the smp_load_acquire() > > > * is inside a spin_lock() and after a write from 0 to non-zero a > > > * spin_lock()+spin_unlock() is done. > > > + * To prevent the compiler/cpu temporarily writing 0 to use_global_lock, > > > + * READ_ONCE()/WRITE_ONCE() is used. > > > * > > > * 2) queue.status: (SEM_BARRIER_2) > > > * Initialization is done while holding sem_lock(), so no further barrier is > > > @@ -342,10 +344,10 @@ static void complexmode_enter(struct sem_array *sma) > > > * Nothing to do, just reset the > > > * counter until we return to simple mode. > > > */ > > > - sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS; > > > + WRITE_ONCE(sma->use_global_lock, USE_GLOBAL_LOCK_HYSTERESIS); > > > return; > > > } > > > - sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS; > > > + WRITE_ONCE(sma->use_global_lock, USE_GLOBAL_LOCK_HYSTERESIS); > > > for (i = 0; i < sma->sem_nsems; i++) { > > > sem = &sma->sems[i]; > > > @@ -371,7 +373,8 @@ static void complexmode_tryleave(struct sem_array *sma) > > > /* See SEM_BARRIER_1 for purpose/pairing */ > > > smp_store_release(&sma->use_global_lock, 0); > > > } else { > > > - sma->use_global_lock--; > > > + WRITE_ONCE(sma->use_global_lock, > > > + sma->use_global_lock-1); > > > } > > > } > > > @@ -412,7 +415,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, > > > * Initial check for use_global_lock. Just an optimization, > > > * no locking, no memory barrier. > > > */ > > > - if (!sma->use_global_lock) { > > > + if (!READ_ONCE(sma->use_global_lock)) { > > > /* > > > * It appears that no complex operation is around. > > > * Acquire the per-semaphore lock. > > > -- > > > 2.31.1 > > > >