Reference count race window

Poul-Henning Kamp phk at phk.freebsd.dk
Thu Jan 2 23:07:50 UTC 2014


In message <D29CB80EBA4DEA4D91181928AAF51538438C0D8B at SACEXCMBX04-PRD.hq.netapp.
com>, "Gumpula, Suresh" writes:


>One such implementation might look like:
>static __inline int
>refcount_acquire(volatile u_int *count)
>{
>        u_int old;
>
>        old = atomic_fetchadd_int(count, 1);
>        return (old != 0);
>}

This would still not be safe. as it would increment the count even if
it failed, and thereby just move the race to the thread to come
past this counter.

I agree that refcount_acquire() needs to return failure (either as
returnvalue or panic) if the refcount was zero, but unless it
panics it SHALL also leave the refcount intact in that case.

I don't think there is any way to implement failure-detecting
refcounts correctly, except by using a compare-exchange style atomic,
which is less efficient than the atomic add.

For that reason, it can be argued that the present design is
faster and that users of the refcount API are required to use
some other means to ensure that grabbing a reference is always
safe.

However, in my experience that usually becomes even more inefficient.

So overall I would probably vote for the compare-exchange model with a
return value for failure.


-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.


More information about the freebsd-hackers mailing list