From owner-svn-src-head@freebsd.org Tue Feb 20 16:27:27 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3B58DF11AFB; Tue, 20 Feb 2018 16:27:27 +0000 (UTC) (envelope-from kib@freebsd.org) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9C6E37EDD5; Tue, 20 Feb 2018 16:27:26 +0000 (UTC) (envelope-from kib@freebsd.org) Received: from tom.home (kib@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id w1KGRB2N034302 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 20 Feb 2018 18:27:14 +0200 (EET) (envelope-from kib@freebsd.org) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua w1KGRB2N034302 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id w1KGRBIV034301; Tue, 20 Feb 2018 18:27:11 +0200 (EET) (envelope-from kib@freebsd.org) X-Authentication-Warning: tom.home: kostik set sender to kib@freebsd.org using -f Date: Tue, 20 Feb 2018 18:27:11 +0200 From: Konstantin Belousov To: Mateusz Guzik Cc: "Bjoern A. Zeeb" , Mateusz Guzik , src-committers , svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r329639 - head/sys/kern Message-ID: <20180220162711.GK94212@kib.kiev.ua> References: <201802201052.w1KAq7jQ057924@repo.freebsd.org> <2A592C68-C6B3-4BAA-975C-02D325292C02@lists.zabbadoz.net> <20180220114241.GH94212@kib.kiev.ua> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.3 (2018-01-21) X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Feb 2018 16:27:27 -0000 On Tue, Feb 20, 2018 at 05:10:52PM +0100, Mateusz Guzik wrote: > On Tue, Feb 20, 2018 at 12:42 PM, Konstantin Belousov > wrote: > > > On Tue, Feb 20, 2018 at 10:58:33AM +0000, Bjoern A. Zeeb wrote: > > > On 20 Feb 2018, at 10:52, Mateusz Guzik wrote: > > > > > > > Author: mjg > > > > Date: Tue Feb 20 10:52:07 2018 > > > > New Revision: 329639 > > > > URL: https://svnweb.freebsd.org/changeset/base/329639 > > > > > > > > Log: > > > > Make killpg1 perform process validity checks without proc lock held. > > > > > > I appreciate all these locking improvements! > > > > > > I would feel a lot more easy about them if the commit message would also > > > detail why these changes are possible (e.g. only read-only variables > > > accessed, or variables only ever accessed thread local, ..) and not just > > > what the change is (which the diff also tells). > > Removing PRS_NEW is certainly not safe. > > > > > As in doing unlocked? I don't see why. You mean it can't be safely > tested once without the lock or it needs to be re-checked after locked? The p_state field is read unlocked and it is possible to not see the last update to it. I believe that it must be re-checked after the proc lock is acquired. > > Due to allproc held at most it can transition from PRS_NEW to PRS_NORMAL. > Thus if non-PRS_NEW is spotted, there is no need to recheck locked. > > As for racing the other way, the loop was already racy against fork. > The only difference I see from that standapoint is that if the race > catches the target locked, it will wait and have higher chances of > seeing it fully formed. > > That is with previous code: > > fork: killpg > > xlock(&allproc); > p->p_state = PRS_NEW; > PROC_LOCK(p); > xunlock(&allproc); > ... > PROC_UNLOCK(p); > slock(&allproc); > PROC_LOCK(p); > if (p->p_state == PRS_NEW) > /* tests true */ > PROC_UNLOCK(p); > sunlock(&allproc); > > ... > PROC_LOCK(p); > p->p_state = PRS_NORMAL; > PROC_UNLOCK(p); > > For this case proc locking in killpg played no role. > > It can catch the process still locked from the area protected by > allproc, which makes no difference in the outcome. > > For when it catches later: > > fork: killpg > xlock(&allproc); > p->p_state = PRS_NEW; > PROC_LOCK(p); > xunlock(&allproc); > ... > PROC_UNLOCK(p); > ... > PROC_LOCK(p); > slock(&allproc); > PROC_LOCK(p); starts.. > p->p_state = PRS_NORMAL; > PROC_UNLOCK(p); > PROC_LOCK(p); ..finishes > if (p->p_state == PRS_NEW) > /* > * tests false, signal > * is delivered > */ > PROC_UNLOCK(p); > sunlock(&allproc); > > But that was not guaranteed to begin with. The new code will simply miss > this case, just like both old and new can miss it in other variations. > > Am I missing something here? p_state is declared to be locked by the proc lock (and proc slock, but I think this is a comment bug). Relying on occational allproc protection is wrong, or re-declare it as being double-protected both by proc lock and allproc. > > -- > Mateusz Guzik