Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Aug 2007 17:37:32 -0700
From:      Alfred Perlstein <alfred@freebsd.org>
To:        Maciej Sobczak <prog@msobczak.com>
Cc:        Pawel Jakub Dawidek <pjd@FreeBSD.org>, freebsd-arch@FreeBSD.org
Subject:   Re: Lockless uidinfo.
Message-ID:  <20070819003732.GA87451@elvis.mu.org>
In-Reply-To: <46C75045.8000503@msobczak.com>
References:  <20070818120056.GA6498@garage.freebsd.pl> <20070818142337.GW90381@elvis.mu.org> <20070818150028.GD6498@garage.freebsd.pl> <20070818155041.GY90381@elvis.mu.org> <20070818161449.GE6498@garage.freebsd.pl> <46C75045.8000503@msobczak.com>

next in thread | previous in thread | raw e-mail | index | archive | help
* Maciej Sobczak <prog@msobczak.com> [070818 13:27] wrote:
> Pawel Jakub Dawidek wrote:
> 
> >thread1 (uifind)		thread2 (uifree)
> >----------------		----------------
> >				refcount_release(&uip->ui_ref))
> >				/* ui_ref == 0 */
> >mtx_lock(&uihashtbl_mtx);
> >refcount_acquire(&uip->ui_ref);
> >/* ui_ref == 1 */
> >mtx_unlock(&uihashtbl_mtx);
> >				mtx_lock(&uihashtbl_mtx);
> >				if (uip->ui_ref > 0) {
> >					mtx_unlock(&uihashtbl_mtx);
> >					return;
> >				}
> >
> >Now, you suggest that ui_ref in 'if (uip->ui_ref > 0)' may still have
> >cached 0? I don't think it is possible, first refcount_acquire() uses
> >read memory bariers (but we may still need ui_ref to volatile for this
> >to make any difference) and second, think of ui_ref as a field protected
> >by uihashtbl_mtx mutex in this very case.
> >
> >Is my thinking correct?
> 
> Yes, but I believe you are too conservative even with the above explanation.
> 
> Unlocking (thread1) and subsequent locking (thread2) of the same mutex 
> guarantees memory visibility between threads, at least if the mutex 
> provides the fundamental release-acquire consistency. In this case, the 
> memory barrier is part of this process itself and you don't need to do 
> anything else to guarantee the visibility of ui_ref == 1 in thread2.
> 
> The only thing to worry about is caching of values in CPU registers 
> (note that this issue is separate from visibility), but these should be 
> prevented by the compiler at the point of mtx_lock. There are basically 
> two ways to guarantee it: either the compiler is too stupid/conservative 
> to cache the value across mtx_lock if it's a function call, or it is 
> smart enough to know (or just see) that there is a membar inside. In any 
> case no register-level caching will take place.
> 
> There should be no need to make anything volatile.

That sounds right, otherwise the reading of the refcount itself in the
previous code would have required special handling.

-Alfred



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070819003732.GA87451>