Page MenuHomeFreeBSD

timerfd: Add tests
Needs ReviewPublic

Authored by jfree on Tue, Mar 10, 12:51 AM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Mar 18, 4:23 AM
Unknown Object (File)
Wed, Mar 18, 4:22 AM
Unknown Object (File)
Tue, Mar 17, 5:35 PM
Unknown Object (File)
Tue, Mar 17, 3:44 AM
Unknown Object (File)
Sun, Mar 15, 2:16 PM
Unknown Object (File)
Wed, Mar 11, 1:15 PM
Unknown Object (File)
Wed, Mar 11, 4:39 AM
Subscribers

Details

Reviewers
markj
imp
arrowd
Summary

Take Jan Kokemuller's timerfd tests from the epoll-shim project,
stripping out code that isn't directly related to FreeBSD.

Diff Detail

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

Event Timeline

jfree created this revision.

I think the tests are ok, though as before the errno checking doesn't seem very useful. I'm also not sure about this leak detection stuff, I would probably inline it into the timerfd.c tests if we're going to keep it. With ATF each test runs in its own process so fd leaks aren't really a problem, and many existing test cases are not careful to close fds.

A bit tangential, but: we found a while back that it was possible to trivially livelock a core by scheduling timeouts of 1ns using EVFILT_TIMER or setitimer(). Basically, it takes longer than the callout interval to execute the callout handler, so the callout handler ends up running in a loop.

As a mitigation, @kib introduced a mechanism to pause these callouts when the owning process receives SIGSTOP or SIGKILL. See itimer_proc_continue() and kqtimer_proc_continue(). Do we need a similar mechanism for timerfds?

A bit tangential, but: we found a while back that it was possible to trivially livelock a core by scheduling timeouts of 1ns using EVFILT_TIMER or setitimer(). Basically, it takes longer than the callout interval to execute the callout handler, so the callout handler ends up running in a loop.

I should note that the current timerfd implementation fails to pass the timerfd__periodic_timer_performance test, which expects 400000000 individual nanosecond timeouts. I usually see 360000000 - 380000000 timeouts printed by the test case. I'm not sure if this performance issue is related to the core livelock in some way. The callout routine (timerfd_expire()) is fairly lightweight, specifying absolute expiration time with maximum precision (no C_PREL() or pr specified).

A bit tangential, but: we found a while back that it was possible to trivially livelock a core by scheduling timeouts of 1ns using EVFILT_TIMER or setitimer(). Basically, it takes longer than the callout interval to execute the callout handler, so the callout handler ends up running in a loop.

As a mitigation, @kib introduced a mechanism to pause these callouts when the owning process receives SIGSTOP or SIGKILL. See itimer_proc_continue() and kqtimer_proc_continue(). Do we need a similar mechanism for timerfds?

Since these timers can be configured in periodic mode, the mitigation is required.

A bit tangential, but: we found a while back that it was possible to trivially livelock a core by scheduling timeouts of 1ns using EVFILT_TIMER or setitimer(). Basically, it takes longer than the callout interval to execute the callout handler, so the callout handler ends up running in a loop.

I should note that the current timerfd implementation fails to pass the timerfd__periodic_timer_performance test, which expects 400000000 individual nanosecond timeouts. I usually see 360000000 - 380000000 timeouts printed by the test case. I'm not sure if this performance issue is related to the core livelock in some way. The callout routine (timerfd_expire()) is fairly lightweight, specifying absolute expiration time with maximum precision (no C_PREL() or pr specified).

Hmm, this sounds like another bug. Even if the callout handler is lightweight, I'm sure it plus the overhead of scheduling and running a callout costs more than 1ns. The livelock issue relates to the problem where it becomes impossible to schedule a thread on a looping core, because the softclock thread which runs the callout handler has high priority.

Hmm, this sounds like another bug. Even if the callout handler is lightweight, I'm sure it plus the overhead of scheduling and running a callout costs more than 1ns. The livelock issue relates to the problem where it becomes impossible to schedule a thread on a looping core, because the softclock thread which runs the callout handler has high priority.

So then the question becomes: what is the minimum amount of time, in the future, that a callout can be scheduled for without missing its activation time?

Say the next expiration is scheduled to happen in 1ns. Instead of actually scheduling that callout to active in 1ns, should I instead schedule the callout for 2ns in the future and when that activates increment the timerfd count +2?

I think this is especially tricky because it depends on system load, as you mentioned in D55790.