Date: Mon, 21 May 2007 22:10:29 +0200 From: Attilio Rao <attilio@FreeBSD.org> To: Bruce Evans <bde@optusnet.com.au> Cc: arch@FreeBSD.org Subject: Re: sched_lock && thread_lock() Message-ID: <4651FCB5.7070604@FreeBSD.org> In-Reply-To: <20070521195811.G56785@delplex.bde.org> References: <20070520155103.K632@10.0.0.1> <20070521113648.F86217@besplex.bde.org> <20070520213132.K632@10.0.0.1> <4651CAB8.8070007@FreeBSD.org> <4651CE2F.8080908@FreeBSD.org> <20070521022847.D679@10.0.0.1> <20070521195811.G56785@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Bruce Evans wrote: > On Mon, 21 May 2007, Jeff Roberson wrote: > > > The function that I described is only linked to vm paging. Statistics are > vital for vm paging, though perfectly up to date statistics might not be. Exactly, this is what I meant too. > Also, atomic ops don't help much for VMCNT_GET() and VMCNT_SET(): > VMCNT_GET(): atomic ops are not used. If they were used, then they would > just reduce race windows, since without a lock the data may change > immediately after you read it, whether or not you read it atomically. > Atomic ops are still strictly needed to give atomic accesses to > variables that cannot naturally be accessed atomically (perhaps because > they are wider than the bus width), but everything in struct vmmeter > is u_int so this is only a problem on exotic hardware. > VMCNT_SET(): atomic ops are used. This doesn't help, since with multiple > writers, without locks there would be races deciding what to write > (starting from unlocked values) and then races writing. I think this > isn't a problem because VMCNT_SET() is only used in initialization code > when only one thread is running. I think your objection about VMCNT_SET() is pretty right, it should not use atomic_* since it is used just for initializations. We can probabilly change it in short times. And as you stated, assuming reads to be atomic is not a problem here since we use volatile and all vmmeter fields are on machine natural boundaries. > We already have inconsistent accesses via PCPU_LAZY_INC(), and I think > all cases where you don't really care about the values can be handled > better by PCPU_LAZY_INC(). (Though I don't like PCPU_LAZY_INC(), since > it gives namespace pollution, a larger race window while combining the > values, complications, and missing support for combining the values > in dead kernels.) Cases that can be handled by PCPU_LAZY_INC() are > distinguished by the variables being monotonically increasing with > time (until wrapping at UINT_MAX breaks them) and nothing except > userland looking at them. The userland accesses are full of races, > but userland doesn't really care. If accessing the pcpu is inefficient, > then PCPU_LAZY_INC() can always use atomic ops if that is less inefficient. Yes, but how do you manage to mantain per-cpu datas and not using per-cpu fields? Do you want it fitting a table? In this case probabilly you will need an extra-lock for the table that will increases overhead. Thanks, Attilio
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4651FCB5.7070604>