Date: Wed, 22 Aug 2007 08:35:52 +0200 From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: John Baldwin <jhb@freebsd.org> Cc: Alfred Perlstein <alfred@freebsd.org>, freebsd-arch@freebsd.org Subject: Re: Lockless uidinfo. Message-ID: <20070822063552.GC4187@garage.freebsd.pl> In-Reply-To: <200708211753.34697.jhb@freebsd.org> References: <20070818120056.GA6498@garage.freebsd.pl> <200708211403.29293.jhb@freebsd.org> <20070821191902.GA4187@garage.freebsd.pl> <200708211753.34697.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--PuGuTyElPB9bOcsM Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Tue, Aug 21, 2007 at 05:53:34PM -0400, John Baldwin wrote: > On Tuesday 21 August 2007 03:19:02 pm Pawel Jakub Dawidek wrote: > > > Memory barriers on another CPU don't mean anything about the CPU thre= ad 2=20 > is=20 > > > on. Memory barriers do not flush caches on other CPUs, etc. Normall= y=20 > when=20 > > > objects are refcounted in a table, the table holds a reference on the= =20 > object,=20 > > > but that doesn't seem to be the case here. [...] > >=20 > > But the memory barrier from 'mtx_lock(&uihashtbl_mtx)' above > > 'if (uip->ui_ref > 0)' would do the trick and I can safely avoid using > > atomic read in this if statement, right? >=20 > Yes, though that may be rather non-obvious to other people, or to yoursel= f 6=20 > months down the road. You should probably document it. Agreed, I added a comment that should explain it. > > > I wouldn't use a more complex algo in uifree() unless the simple one = is=20 > shown=20 > > > to perform badly. Needless complexity is a hindrance to future=20 > maintenance. > >=20 > > Of coure we could do that, but I was trying really hard to remove > > contention in the common case. Before we used UIDINFO_LOCK() in the > > common case, now you suggesting using global lock here, and I'd really, > > really prefer using one atomic only. >=20 > *sigh* You ignored my last sentence. You need to think about other peop= le=20 > who come and read this later or yourself 12 months from now when you've p= aged=20 > out all the uidinfo stuff from your head. >=20 > Hmm, what happens if you get this: >=20 > thread A > -------- >=20 > refcount_release() - drops to 0 >=20 > preempted >=20 > thread B > -------- > uihold() - refcount goes to 1 > ... > uifree() - refcount goes to 0 > removes object from table and frees it >=20 > resumes >=20 > mtx_lock(&uihashtbl); >=20 > sees refcount of 0 so tries to destroy object again >=20 > *BOOM* (corruption, panic, etc.) Grr, good catch. > This is the race that the current code handles by taking a reference > on the uid while it drops the uidinfo lock to acquire the table lock. >=20 > Probably you need to not drop the last reference unless you hold the=20 > uihashtbl_mtx, which means not using refcount_release() and manually use = an=20 > atomic_cmpset_int() if the refcount is > 1 to drop a ref to optimize the= =20 > common case: >=20 > old =3D uip->ui_refs; > if (old > 1) { > if (atomic_cmpset_int(&uip->ui_refs, old, old - 1)) > return; > } >=20 > mtx_lock(&uihashtbl_mtx); > if (refcount_release(&uip->ui_refs)) { > /* remove from table and free */ > } > mtx_unlock(&uihashtbl_mtx); How about we relookup it after acquiring the uihashtbl_mtx lock? Something like this (comments removed): uid_t uid; uid =3D uip->ui_uid; if (!refcount_release(&uip->ui_ref)) return; mtx_lock(&uihashtbl_mtx); uip =3D uilookup(uid); if (uip !=3D NULL && uip->ui_ref =3D=3D 0) { LIST_REMOVE(uip, ui_hash); mtx_unlock(&uihashtbl_mtx); FREE(uip, M_UIDINFO); return; } mtx_unlock(&uihashtbl_mtx); I updated the patch at: http://people.freebsd.org/~pjd/patches/uidinfo_waitfree.patch --=20 Pawel Jakub Dawidek http://www.wheel.pl pjd@FreeBSD.org http://www.FreeBSD.org FreeBSD committer Am I Evil? Yes, I Am! --PuGuTyElPB9bOcsM Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.4 (FreeBSD) iD8DBQFGy9lIForvXbEpPzQRAkyOAJoCwVBu1Fnr1tcYreempKrSrzJg+ACg2Vw9 T95TsOerhH6jnArM9tD3pno= =kw9m -----END PGP SIGNATURE----- --PuGuTyElPB9bOcsM--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070822063552.GC4187>