The leap second bug
- Running date -s "`date`" seems to be an effective workaround.
- See this note from John Stultz for a preliminary diagnosis of the problem; he also has a fix available for testing.
More soon.
Posted Jul 2, 2012 15:12 UTC (Mon)
by theophrastus (guest, #80847)
[Link] (2 responses)
Posted Jul 2, 2012 15:17 UTC (Mon)
by corbet (editor, #1)
[Link] (1 responses)
Posted Jul 2, 2012 16:14 UTC (Mon)
by Baylink (guest, #755)
[Link]
Posted Jul 2, 2012 17:22 UTC (Mon)
by fest3er (guest, #60379)
[Link] (2 responses)
I don't understand the difficulty. Leap seconds, minutes, hours, days, years are simply adjustments to our perception of 'now' and should be handled in the same way as all other date conversion problems. Elapsed time is contiguous and constant*; our interpretation of elapsed time into 'when' is discontiguous where adjustments are concerned.
* Fairly constant in our gravity well. Time passes at a slightly different pace up in orbit.
Posted Jul 3, 2012 1:53 UTC (Tue)
by kevinm (guest, #69913)
[Link]
(POSIX time_t isn't the number of seconds since 01-JAN-1970 00:00 UTC - it's the number of whole days since then multiplied by 86400 plus the number of seconds since the most recent midnight UTC).
Posted Jul 3, 2012 9:38 UTC (Tue)
by Tobu (subscriber, #24111)
[Link]
Posted Jul 2, 2012 18:04 UTC (Mon)
by bluss (guest, #47454)
[Link] (5 responses)
Posted Jul 2, 2012 18:49 UTC (Mon)
by dirtyepic (guest, #30178)
[Link] (4 responses)
I imagine the NASDAQ people might also have a problem with this.
Posted Jul 2, 2012 19:55 UTC (Mon)
by cmccabe (guest, #60281)
[Link] (3 responses)
I guess maybe you should be using CLOCK_MONOTONIC then? That is what it's for-- monotonic time.
Posted Jul 4, 2012 6:27 UTC (Wed)
by butlerm (subscriber, #13312)
[Link] (2 responses)
Posted Jul 4, 2012 10:03 UTC (Wed)
by cmccabe (guest, #60281)
[Link] (1 responses)
Having your 1 second mutex timedwait last for an hour because someone set the wall clock time back an hour, on the other hand, is not useful. Having your 1 second wait take 2 seconds because of a leap second is not useful.
Assuming that wall-clock time is properly synchronized across all nodes in a distributed system is usually not a good idea. It introduces operational complexity and more things to go wrong. And even the best maintained, properly synchronized clocks aren't usually really all that synchronized.
What we have here is a bad default, unfortunately. Most timeouts should not be in terms of wall-clock time-- ideally, none, except for calendar programs and similar.
Posted Jul 5, 2012 3:03 UTC (Thu)
by dirtyepic (guest, #30178)
[Link]
Posted Jul 2, 2012 18:48 UTC (Mon)
by slashdot (guest, #22014)
[Link] (16 responses)
OK, the terminal idiocy is right there.
I mean, libc already has to handle timezones when converting to human time, so surely it can handle leap seconds as well, allowing an unambiguous absolute time representation which is also monotonic if time is correctly set and synchronized.
One would think that the POSIX standard committee would not approve such a totally broken interface that jumps back one second on perfectly working systems, but clearly that's not the case.
And obviously whoever used CLOCK_REALTIME to do timeouts not tied to real time is also not a genius.
I also fail to see why we have leap seconds at all, given that I don't think anybody cares if the sun sets a minute later on average, but that's not the real issue.
Posted Jul 2, 2012 19:01 UTC (Mon)
by slashdot (guest, #22014)
[Link] (12 responses)
Are these polling loops or perhaps code that fails if something holds a mutex for more than a second?
Do these clowns seriously put such crap in production software?
Posted Jul 2, 2012 20:04 UTC (Mon)
by clugstj (subscriber, #4020)
[Link]
Posted Jul 3, 2012 7:41 UTC (Tue)
by farnz (subscriber, #17727)
[Link] (4 responses)
As an example from a codebase I worked on (under VxWorks, not Linux, but the idea carries over) - you want a decoder thread to run immediately after the graphics thread has finished rendering a frame to screen, to repopulate the queue of decoded frames (if needed due to timestamps being missed by the graphics thread). Your graphics thread is set up to sync to vblank, and you know the expected frame rate; you don't want the decoder thread to stall completely if the graphics stalls due to complex rendering.
You know that in your environment, the decoder thread keeps a minimum of 5 decoded frames queued and ready to go; that's 80 milliseconds. You expect the graphics thread to wake the decoder up every 16 milliseconds, but know that if it doesn't, you can wait up to 50 milliseconds before you urgently need to catch up to ensure that when the graphics thread recovers, it has current data to display. You therefore set the timeout on the mutex sleep decoder-side to 50 milliseconds, knowing that if the graphics thread stalls for whatever reason, you will keep the queue filled with current frames.
Posted Jul 3, 2012 19:34 UTC (Tue)
by slashdot (guest, #22014)
[Link] (3 responses)
One would expect the decoder to read from the network (sleeping if no data is available) and decode frames, putting them in a shared queue, while discarding any that have a "too old" timestamp when a new one is queued (and/or discarding to keep the queue smaller than a fixed limit), and waking up the graphics thread on empty -> non-empty transition.
The graphics thread simply removes the oldest one from the queue (or waits for one to appear if the queue is empty), waits for vblank, and displays it.
No idea why you would want to hold mutexes for milliseconds (which is generally not ideal in any case), or sleep for any time interval, instead of just waiting for network I/O, for vblank, and for the decoding queue being non-empty.
Posted Jul 4, 2012 9:20 UTC (Wed)
by farnz (subscriber, #17727)
[Link] (2 responses)
The device in question did encoded video stream conformance checking. We had a total of four interesting threads; the statistics gathering thread, the automatic reaction thread, the decoder thread, and the render thread, and three input feeds.
The statistics gathering thread gathers interesting information about the stream, and stores it for the automatic reaction thread and the render thread to use. This can take up to 4ms per frame per input, depending on the instantaneous complexity of the inputs (it does partial decode of video and audio to approximate some interesting measures of the video and audio), but normally takes about 1ms per input.
The automatic reaction thread applies a set of business rules against the statistics, and can trigger external systems to react to an out-of-bounds condition, plus indicates to the render thread that it should show an alarm state to any human user. This takes no more than 1ms with the most complicated rules permitted.
The render thread takes 1ms to render the statistics and any alarm and a further 4ms to update the video box.
The decode thread takes up to 4ms to decode each frame of a selected input. As decoded video is only for presentation to a user, it is considered low importance.
When you add it up, the statistics take 12ms. The reaction thread gets us to 13ms. The render thread needs 1ms if not showing video, for 14ms total, or 5ms if showing video, for 18ms total. The decode thread can add another 4ms to that (22ms total), and our deadline is 16.66ms per frame. We are 6ms over budget for a single frame, in the worst case.
We took this to our product managers, and were told that as long as the automatic reactions happen every frame, we would be OK if the UI was late (render and decode threads), but that they'd want to see at least 1 in every 4 frames of video. This was because the automation was expected to run 24/7 as a set-and-forget system, but the UI would be something only used by some customers at critical times, and could be slow to update.
We handled this by making the reaction thread highest possible priority; the stats thread is the next priority down, as it's more important to have the automated stuff happening than it is to keep the user updated (we expected most people to treat the product as set-and-forget). The decode thread is the next highest priority, as we want to complete a frame decode once we've started it, so that there is some video to display - we don't want to be unable to ever decode a frame in time to display it. The render thread runs at a low priority. The mutex then permits the render thread to release the decode thread when the render thread has enough time left until its next deadline that it should be safe to decode a frame; if the render thread doesn't reach this point in 3 frame times, the decode thread will start anyway, and claim the CPU (delaying the render thread, as it's higher priority, and this is all SCHED_FIFO scheduling).
Given the constraints, how would you have implemented it?
Posted Jul 5, 2012 2:35 UTC (Thu)
by slashdot (guest, #22014)
[Link] (1 responses)
This can for instance be accomplished by giving higher priority to the render thread, and having it wait for the decode thread if N frames have been output with less than K decoded video frames.
Alternatively, decide on a fixed rate and simply sequentially decode one frame and then display N stats frames with that same video frame.
The latter is less flexible but might allow tricks like decoding directly to the framebuffer and then XORing each stats overlay on and off, thus never copying decoded video.
Anyway, non-embedded software does not usually have those issues.
Posted Jul 5, 2012 5:20 UTC (Thu)
by farnz (subscriber, #17727)
[Link]
Fixed rate is out - while we only guaranteed a low frame rate, we also wanted to achieve a high frame rate if possible, as in the common case (main feed to transmitter, received transmission, low bit rate "we are sorry for any inconvenience" feed), we can meet full frame rate.
Your suggested solution has the same problem as a low timeout - in terms of system overhead, it's identical, plus it now needs extra analysis to verify that the decode thread will run often enough. The advantage of a 50ms timeout is that it's obvious that the decode thread will run once every 50ms in the worst case. In general, it's a bad idea to introduce complexity for the maintenance programmer - if it's not obvious, there's a good chance they'll miss it, make an apparently unrelated change, and now the render thread isn't kicking until you've missed 4 frames, instead of waking up after you've missed 3.
And in non-embedded systems, you get small timeouts by calculation - e.g. "wait for the result of the work I've just asked another thread to do, or for the application layer keepalive timeout to expire". If you've already done 239 seconds of work on this request, and the keepalive timer is 4 minutes, the computed time to sleep will be under a second. Adding extra application code to make the timeout sloppy (e.g. send the keepalive early if the remaining is less than 5 seconds) is extra complexity for a rare case that isn't even needed in the absence of kernel/libc bugs (and one of the powerful points of open source is that you can fix kernel/libc bugs if they affect you, instead of having to have everyone work around them).
Posted Jul 4, 2012 2:13 UTC (Wed)
by jzbiciak (guest, #5246)
[Link] (5 responses)
Posted Jul 9, 2012 23:37 UTC (Mon)
by dlang (guest, #313)
[Link] (4 responses)
Posted Jul 10, 2012 0:14 UTC (Tue)
by jzbiciak (guest, #5246)
[Link] (3 responses)
I had to disable various extensions to slay the memory leaks that were driving Firefox up to the 10-12GB range on me regularly. GC would regularly insert 3+ second pauses and run up the soft-fault count. (At least, I assume that's what it was doing... I had soft-fault counts in the billions.)
Posted Jul 10, 2012 0:19 UTC (Tue)
by dlang (guest, #313)
[Link] (2 responses)
This has been going on for several years, but is getting less common on recent versions (I am now running the Aurora versions everywhere, so my 'recent' may be newer than your 'current' :-)
Posted Jul 10, 2012 0:34 UTC (Tue)
by jzbiciak (guest, #5246)
[Link] (1 responses)
Posted Jul 10, 2012 1:01 UTC (Tue)
by dlang (guest, #313)
[Link]
Posted Jul 2, 2012 19:58 UTC (Mon)
by chloe_zen (guest, #8258)
[Link] (2 responses)
Too late to reconsider it, IMO.
Posted Jul 2, 2012 23:33 UTC (Mon)
by slashdot (guest, #22014)
[Link]
The thing is that you can only get UTC h:mm:ss and local timezone seconds using modulus on time_t, due to half-hour-offset timezones, DST and irregular month lengths.
Now, you generally either want to display UTC date+time or local h:mm:ss at least, neither of which you can do without calling library functions, so maybe not much or anything will break?
I'm not sure I'd risk it though, and not adding leap seconds ever again to UTC seems a much better solution.
Posted Jul 4, 2012 6:13 UTC (Wed)
by butlerm (subscriber, #13312)
[Link]
That is a perfectly adequate (if not ideal) convention for use in generating representations of civil time. Month, day, year and so on. The problem comes where programs (and kernels) are designed around the preposterous presumption that POSIX time has any reliable relationship to real time.
That might work reasonably well when your timeouts are measured in a cardinal number of seconds greater than two, but experience clearly demonstrates that using POSIX time (or UTC) for anything requiring sub-second accuracy is foolish in the extreme. It amounts to designing a system to fail with a high probability every three or four years.
Posted Jul 2, 2012 20:42 UTC (Mon)
by man_ls (guest, #15091)
[Link] (1 responses)
I think that my two home systems could have been affected: my desktop (i3, two cores) started consuming a whole core whenever I started Firefox or Chrome, for whatever reason. When I shut down both then it went to normal. And again when I started any of them, CPU spikes.
My SheevaPlug just stopped responding to certain commands,
Does this bug solve both mysteries (happening at about the right time IIRC), or am I retconning the solution?
Posted Jul 4, 2012 21:20 UTC (Wed)
by idupree (guest, #71169)
[Link]
Posted Jul 2, 2012 23:21 UTC (Mon)
by adamgundy (subscriber, #5418)
[Link] (1 responses)
Posted Jul 2, 2012 23:27 UTC (Mon)
by adamgundy (subscriber, #5418)
[Link]
Posted Jul 2, 2012 23:41 UTC (Mon)
by camh (guest, #289)
[Link]
Posted Jul 3, 2012 1:57 UTC (Tue)
by kevinm (guest, #69913)
[Link] (1 responses)
Posted Jul 3, 2012 4:38 UTC (Tue)
by adisaacs (subscriber, #53996)
[Link]
Posted Jul 3, 2012 13:55 UTC (Tue)
by welinder (guest, #4699)
[Link]
Seriously, we _knew_ something unusual time-wise was coming up.
It's like sales tax being considered an unexpected expense.
The leap second bug
It never occurred to me to implement a "reparent these comments" functionality. I could do it in SQL, I guess, but we believe that a natural aversion to typing SQL directly at the production site is a healthy thing. So the best thing, for those who are interested, is to follow this pointer to said comments.
The leap second bug
The leap second bug
The leap second bug
The leap second bug
If you want to break convention and use TAI64 timestamps rather than POSIX timestamps (which are ambiguous when a leap second is inserted), you can use djb's libtai. Of course, you won't be protected from leap second bugs in the kernel or glibc. And these can only be used internally, but you should already be using RFC 3339 dates for interoperability anyway. Finally you need to maintain your own leap second table without the help of NTP. Or for many uses when the timestamps won't leave your process, you can use clock_gettime with CLOCK_MONOTONIC.
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
Who thought of this dumb idea?
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
The leap second bug
What? When? Why? Whatever?
The leap second bug
df -h
worked while free
yielded an I/O error after a while. Not a common occurrence; I had to restart it and it went fine.
The leap second bug
just a warning: I've seen some very odd behavior with 'clearing' the bug by setting the date, then stopping/starting ntpd. it seems to throw the time forward an hour plus some minutes. waiting a minute or two before starting ntpd seems to be OK..
The leap second bug
sigh. spoke too soon. at some point after the initial date reset, possibly in combination with ntpd (and maybe not..) the time appears to jump forward to the next nearest hour. this may cause havoc, depending on your software.
ntpdate will fix it, but you have to wait for it to happen (5-10 minutes?), then use ntpdate to correct the problem.
The leap second bug
The leap second bug
The leap second bug
That's a different bug, 6b43ae8a619d (ntp: Fix leap-second hrtimer livelock).
The leap second bug
The leap second bug
We didn't test what would happen. As a community -- developers
and technical users -- that's an embarrassment! Brown bags for
everyone.