Page MenuHomeFreeBSD

buf_ring: support different lock classes
AcceptedPublic

Authored by glebius on Sat, Sep 5, 5:50 PM.
Tags
None
Referenced Files
F171486647: D59457.id185946.diff
Fri, Sep 11, 10:05 AM
F171463046: D59457.id186031.diff
Fri, Sep 11, 6:13 AM
F171377906: D59457.id186170.diff
Thu, Sep 10, 7:18 PM
F171366117: D59457.id186031.diff
Thu, Sep 10, 5:20 PM
F171365128: D59457.id186150.diff
Thu, Sep 10, 5:10 PM
F171364248: D59457.id186150.diff
Thu, Sep 10, 5:00 PM
F171360705: D59457.id186170.diff
Thu, Sep 10, 4:24 PM
Unknown Object (File)
Thu, Sep 10, 9:59 AM

Details

Reviewers
kib
markj
gallatin
kp
Group Reviewers
Src Committers
Summary

And enable locking assertions for INVARIANTS kernel.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76605
Build 73488: arc lint + arc unit

Event Timeline

@kp added you since it touches OpenVPN
@gallatin @kp note dependency on D59455

  • Use _Generic() instead of transparent union.
This revision is now accepted and ready to land.Sun, Sep 6, 10:43 PM

This looks like it contains other changes from the diff stack. Did you mean to do that?

This looks like it contains other changes from the diff stack. Did you mean to do that?

Nevermind -- I see that you combined the changes. Sorry for the noise.

sys/sys/buf_ring.h
363

There is rwlock_padalign too.

368

Wouldn't it be better to add a standalone macro, lock2lock_object() or whatever, to sys/lock.h which maps a lock pointer to its lock object? This is pretty similar to the macro in D59456.

I see that some lock types are excluded from this list, but it's not clear why. buf_ring just asserts that the lock is held. It's fine to use a sleepable lock AFAICS. (And rmlocks can be sleepable anyway.)

sys/sys/buf_ring.h
368

Note that macros in this revision and D59456 are different. buf_ring supports lockless initialization, and thus this macro has extra casts. I really don't like that, but this is problem of the _Generic() feature. Alternative would be to provide a NULLLOCK define that would be a lock-typed NULL pointer. That won't require a big sweep over the kernel, there is only one consumer that passes NULL.

markj added inline comments.
sys/sys/buf_ring.h
368

Yes, you still need to handle a NULL pointer here, but the default case can be redirected to a central macro. Maybe something for a separate revision, if we grow a third use of _Generic for matching lock types.

there is only one consumer that passes NULL.

I see two, if_ovpn and ip_mroute. ip_mroute's use of buf_ring is silly anyway, all operations are serialized by a write lock, (MRW_WLOCK), I believe, so buf_ring is not enabling any extra concurrency.

This revision now requires review to proceed.Mon, Sep 7, 5:38 PM
sys/sys/buf_ring.h
368

I see that some lock types are excluded from this list, but it's not clear why. buf_ring just asserts that the lock is held. It's fine to use a sleepable lock AFAICS. (And rmlocks can be sleepable anyway.)

IMHO, it is better not to throw unused and untested types into the macro. I agree that speculatively there is nothing that would prevent them working. However, I'd prefer to see them added upon first use case.

One other side effect of this support advertisement is that we actually encourage to use locks that are already known to have better alternatives. For example, for rmlock it is already clear that probably every its use in the network stack can be substituted by the net epoch and change is going to be beneficial. Adding rmlock here will also increase grep count of rmlock across kernel, skewing rough estimates on its usage.

sys/sys/buf_ring.h
62–67

IMO it is not worth fighting for the !KERNEL case to save one pointer.

201

Could BR_LOCK_ASSERT() include the check for br->lock not being NULL?

sys/sys/buf_ring.h
62–67

It is not about saving a pointer, it is about keeping it compilable.

201

If it is NULL, of course it would panic on NULL dereference and line number will point right here. We will lose only the diagnostic message. IMHO, not worth overloading the INVARIANTS kernel with extra branches just to provide a diagnostic message on a stupid mistake.

sys/sys/buf_ring.h
62–67

And how it prevents compilation?
You can include sys/_lock.h unconditionally. Or you could forward-declare struct lock_object.

sys/sys/buf_ring.h
62–67

What do we gain having unused pointer? The BR_LOCK_ASSERT() still needs to be nothing to get it compilable. IMHO, easier to just remove the unused member, rather then cruft extra stuff to make it compilable.

Note that this header is not supposed to be used by userland programs to read kernel buf_rings via kvm(3)! It is userland mode today is merely for testing, potentially if someone wants to have a buf_ring in a userland program.

sys/sys/buf_ring.h
62–67

We get less confusion at the debugging time for userspace. Also we get less #ifdefs in the sources, because for instance BR_LOCK_ASSERT() can be used without #ifdef _KERNEL around it.

The use of buf_ring as a userspace tool was my main reasoning for this suggestion.

  • Keep br_lock in user mode.
This revision is now accepted and ready to land.Mon, Sep 7, 8:52 PM

I'd have just removed BUFRING_DEBUG myself..