Page MenuHomeFreeBSD

Detect some attempts to destroy a condvar with waiters.
ClosedPublic

Authored by markj on Mar 7 2019, 6:09 PM.
Tags
None
Referenced Files
F82155980: D19496.id.diff
Fri, Apr 26, 12:42 AM
F82153206: D19496.id54810.diff
Fri, Apr 26, 12:09 AM
F82148980: D19496.id54853.diff
Thu, Apr 25, 11:27 PM
F82121412: D19496.diff
Thu, Apr 25, 5:59 PM
Unknown Object (File)
Jan 13 2024, 11:06 AM
Unknown Object (File)
Dec 20 2023, 3:28 AM
Unknown Object (File)
Aug 1 2023, 4:37 AM
Unknown Object (File)
Aug 1 2023, 4:35 AM
Subscribers

Details

Summary

The check is racy if the associated mutex is not held, but in that case
a race is present anyway, so the situation is not made worse.

Add a couple of tests, one which direct checks that we return EBUSY as
desired, and one which verifies that one can destroy a condvar
immediately after waking up sleepers. This will help catch bugs like
the one referenced in r283250 (there it was the kernel's internal
condvar implementation).

Diff Detail

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

Event Timeline

This looks right to me. The only change I had locally is that I had added a helper function in thr_umtx.h since that seemed to match the style of other code in libthr:

static inline int
_thr_ucond_has_waiters(struct ucond *cv)
{
    return (cv->c_has_waiters != 0);
}

and then used that instead of looking at cvp->kcond directly. I don't mind either way though.

In D19496#417290, @jhb wrote:

This looks right to me. The only change I had locally is that I had added a helper function in thr_umtx.h since that seemed to match the style of other code in libthr:

static inline int
_thr_ucond_has_waiters(struct ucond *cv)
{
    return (cv->c_has_waiters != 0);
}

and then used that instead of looking at cvp->kcond directly. I don't mind either way though.

I considered this, but note that the tests are different depending on the condvar type, and there is existing code in thr_cond.c and thr_umtx.c that checks the field values directly.

It was only a minor suggestion as at the time it seemed more consistent. In my patches I hadn't handled the pshared case yet either fwiw.

This revision is now accepted and ready to land.Mar 7 2019, 7:12 PM

Two questions:

  • is there a test case for the EBUSY behavior?
  • is there a reason why one of the test cases was ifdef’ed FreeBSD, but the other wasn’t?
In D19496#417321, @ngie wrote:

Two questions:

  • is there a test case for the EBUSY behavior?

Yes, destroy_busy().

  • is there a reason why one of the test cases was ifdef’ed FreeBSD, but the other wasn’t?

The code change implements non-standard behaviour, and the test for that behaviour may fail on conforming implementations of the pthread API (like NetBSD's). The other test is for behaviour that is specifically permitted by the standard, so there's no reason to ifdef.

ngie added a subscriber: jilles.

I missed the test for EBUSY. Thank you for pointing that out!

CCing @jilles, just in case they want to chime in. Does this also need a doc update?

Answering myself: no, it’s already documented.

This revision was automatically updated to reflect the committed changes.