From owner-freebsd-current@FreeBSD.ORG Fri Jul 28 13:33:19 2006 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AF8B516A4F2 for ; Fri, 28 Jul 2006 13:33:19 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from server.baldwin.cx (66-23-211-162.clients.speedfactory.net [66.23.211.162]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1F85A43D53 for ; Fri, 28 Jul 2006 13:33:17 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from zion.baldwin.cx (zion.baldwin.cx [192.168.0.7]) (authenticated bits=0) by server.baldwin.cx (8.13.4/8.13.4) with ESMTP id k6SDXAWo086102; Fri, 28 Jul 2006 09:33:17 -0400 (EDT) (envelope-from jhb@freebsd.org) From: John Baldwin To: Brian Candler Date: Fri, 28 Jul 2006 09:28:36 -0400 User-Agent: KMail/1.9.1 References: <200607251254.k6PCsBef092737@lurza.secnetix.de> <200607271058.13055.jhb@freebsd.org> <20060728121525.GA44917@uk.tiscali.com> In-Reply-To: <20060728121525.GA44917@uk.tiscali.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200607280928.36573.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [192.168.0.1]); Fri, 28 Jul 2006 09:33:17 -0400 (EDT) X-Virus-Scanned: ClamAV 0.87.1/1624/Thu Jul 27 13:11:25 2006 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-4.4 required=4.2 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.1.0 X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on server.baldwin.cx Cc: freebsd-current@freebsd.org, Oliver Fromme Subject: Re: vmstat's entries type X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Jul 2006 13:33:19 -0000 On Friday 28 July 2006 08:15, Brian Candler wrote: > On Thu, Jul 27, 2006 at 10:58:12AM -0400, John Baldwin wrote: > > That these counters are for stats. :) You always have a race when reading the > > amount, so you can choose what is "good enough" to satisfy the conflicting > > requirements of "cheap" and "accurate". To me, the cheapness of add+adc > > (compared to say, a cmpxchg8b loop with a branch, etc.) is worth it if you > > have this rare race. > > You can work around the problem when reading - e.g. read twice and check the > values are close. > > But is add + adc safe for update? What about the following: > > - processor 1 reads low32 as FFFFFFFF > - processor 2 reads low32 as FFFFFFFF > - processor 1 writes low32 as 00000000 and sets carry > - processor 2 writes low32 as 00000000 and sets carry > - processor 1 adds 1 to high32 > - processor 2 adds 1 to high32 > > I'm not saying this sequence can definitely occur - I'm thinking from a > general point of view, and I don't know the i386 instruction set. It just > seems plausible. > > OTOH, if the above race can occur, it would imply that even a simple 32-bit > counter update could lose counts. If you do a 'lock add' (atomic add) for the first 'add' this race won't occur. Because the adc wrapping so rare (relatively, you'd have to have 4 billion atomic add's occur in the time it takes 2 different CPU's to do the pair of instructions) you don't need to use 'lock' for the adc under the assumption that simultaneous adc instructions (that aren't just effective nops) won't happen often. However, I've just thought of a problem with that. :( Even if carry is clear, 'adc foo, $0' isn't a NOP, it still wants to do a read-modify-write, so you could use an update to high32 if you have two CPUs do this: CPU1 : bump low from ffffffff to 00000000 CPU2 : bump low from 00000000 to 00000001 CPU1 : adds 1 to high32 CPU2 : adds 0 to high32 and CPU2 reads an old value of high32 to add 0 to that is prior to CPU1's update to high32. To fix that you'd have to either use 'lock' with both instructions, or use a branch to only do adc when it's not a nop. So more like this to increment a counter: lock incl counter jnc 1f lock incl counter+4 1: -- John Baldwin