Page MenuHomeFreeBSD

Add support for blocking waits to refcounts.
ClosedPublic

Authored by jeff on Aug 13 2019, 8:02 PM.
Tags
None
Referenced Files
F102558814: D21254.id60763.diff
Thu, Nov 14, 1:32 AM
Unknown Object (File)
Mon, Nov 11, 5:51 AM
Unknown Object (File)
Tue, Nov 5, 5:29 AM
Unknown Object (File)
Fri, Nov 1, 1:04 AM
Unknown Object (File)
Tue, Oct 29, 2:27 PM
Unknown Object (File)
Fri, Oct 25, 5:58 AM
Unknown Object (File)
Fri, Oct 25, 5:58 AM
Unknown Object (File)
Fri, Oct 25, 5:57 AM
Subscribers

Details

Summary

This adds a wait bit to refcount with an atomic sleep. Consumers that use this facility need to be aware that specific count values can not be examined directly.

When a counter is saturated this will block forever.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

jeff added reviewers: jhb, markj.

I'm not really crazy about this to be honest. refcount_release() gets inlined hundreds if not thousands of times into various functions. Now all of those callers are polluted with extra dead branch to call wakeup(). The fences in refcount_release() also don't make sense when refcount_wait() is used since a refcount of 0 doesn't mean that the protected object is unreachable, the way you'd normally expect a refcount to work. I would argue that this use-case would be better served by a new KPI or something open-coded.

That said, I don't see any technical issues aside from the nits I pointed out.

sys/sys/refcount.h
45 ↗(On Diff #60756)

The use of bit 31 meant that we could detect saturation with a single js instruction after the acquire, but that's no longer true with this change.

85 ↗(On Diff #60756)

Extra newline.

88 ↗(On Diff #60756)

We should assert some bound on n, probably 2^30?

Address some of Markj's feedback. Move the last ref drop into a dedicated function to lessen text bloat.

sys/sys/refcount.h
118 ↗(On Diff #60763)

On underflow, we want to call refcount_release_last() to reset the counter value. But now that won't happen since this is an unsigned comparison.

119 ↗(On Diff #60763)

Style: missing parens.

sys/kern/kern_synch.c
55 ↗(On Diff #60809)

This sorts before resourcevar.h.

363 ↗(On Diff #60809)

Can't the cmpset fail spuriously on LL/SC platforms if the cache line is concurrently modified?

markj added inline comments.
sys/kern/kern_synch.c
363 ↗(On Diff #60809)

Never mind, that only applies to fcmpset.

This revision is now accepted and ready to land.Aug 15 2019, 7:34 PM
kib added inline comments.
sys/kern/kern_synch.c
370 ↗(On Diff #60809)

There is no _rel at the beginning of the function. You need to point to the refcount_releasen().