Year 2038 preparations in 3.17
Much of the work involves changes to two structures used within the kernel: union ktime (usually referred to as ktime_t) and struct timespec. The ktime_t structure was introduced with the high-resolution timer patch set back in 2006; it is meant to be an opaque type for the storage of time values within the kernel. Indeed, it is sufficiently opaque that its definition varies widely depending on the underlying architecture.
For 64-bit systems, ktime_t has always been a simple integer count of nanoseconds. This "scalar" format is easy to manipulate and perform arithmetic on — as long as the CPU has fast 64-bit operations. Since such operations tend to be absent on 32-bit systems, ktime_t has often been defined differently there; it is represented as a structure with separate, 32-bit fields for seconds and nanoseconds. Kernel code uses a set of accessor functions for working with ktime_t values, so the difference in representation is well hidden and does not affect how the rest of the kernel works.
That difference will be rather less well hidden in 2038, though, when the 32-bit seconds field overflows with all the rest. So, for things to keep working in 2038, the ktime_t structure will have to change. One of the first changes merged for 3.17 is to simply get rid of the non-scalar form of ktime_t and force all architectures to use the 64-bit nanosecond count representation. This change may slow things down on 32-bit systems; in particular, conversions from other time formats may be significantly slower. But, as noted in the changelog, the ARM and x86 architectures were already using the scalar format anyway, so they will not get any slower.
Regardless of whether conversions between ktime_t and other formats are fast or not, avoidance of those conversions when possible seems like a promising way of optimizing code within the kernel. The 3.17 changes include a number of time-format changes within various kernel subsystems, causing them to just work with straight nanosecond time values. The result is generally a simplification of the code and, presumably, faster execution.
The other time-related structure used heavily within the kernel is struct timespec:
struct timespec { __kernel_time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
The __kernel_time_t type is just another name for time_t in current kernels; it is, thus, a 32-bit value on 32-bit systems. Unlike ktime_t, though, struct timespec cannot just be changed; it is used in user space as well and is a part of the kernel's ABI. What has been done instead in 3.17 is to add a new structure:
struct timespec64 { time64_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
On 64-bit systems, this structure is identical to struct timespec. Within the core timekeeping code, every struct timespec has been changed to be struct timespec64 instead. The interfaces providing access to timekeeping functionality to the rest of the kernel have been tweaked to hide this change (so far), and a new set of interfaces has been added for code that is using struct timespec64. After this change, there are no more time values using 32-bit seconds counts in the timekeeping core.
The result of all this work is a long way from a solution to the year-2038 problem. But it is one important step in that direction: the core timekeeping code within the Linux kernel will no longer have problems when 2038 rolls around. With a couple more steps, a full solution to the problem may well be in sight. The first of those steps is to push use of struct timespec64 outward from the timekeeping core into the rest of the kernel. This task may involve a fair amount of work, but it is an example of the sort of evolutionary change that the kernel community is relatively good at. Given a bit of time, kernel code should be almost entirely free of year-2038 issues.
The harder step, of course, is to incorporate year-2038-safe structures
into the kernel ABI and get user-space developers to change their code
over. That will require cooperation with user-space developers from the
C-library level on up and a lot of thought into how this change can be made
with a minimum of pain. One should not expect it to happen quickly. But
the problem is now well established on the radar of many of the relevant
developers, so the chances of resolving most of the problems without a
last-minute panic seem to be reasonably good. The first steps have been
taken; hopefully the rest will follow before too long.
Index entries for this article | |
---|---|
Kernel | Year 2038 problem |
Posted Aug 7, 2014 4:15 UTC (Thu)
by brouhaha (subscriber, #1698)
[Link] (10 responses)
Posted Aug 7, 2014 7:53 UTC (Thu)
by Villemoes (subscriber, #91911)
[Link] (9 responses)
Posted Aug 7, 2014 15:03 UTC (Thu)
by rriggs (guest, #11598)
[Link] (1 responses)
Posted Aug 7, 2014 19:37 UTC (Thu)
by zlynx (guest, #2285)
[Link]
I see it as more likely that everyone programs to a intermediate language like the LLVM or .NET IR instead of native machine code and that IR language uses infinite width data types.
By 2262 if we still program computers at all, we're probably writing in an abstraction layer that is many levels away from the real machine.
However, the real hardware is going to have a real number of wires, and the number of wires connected to the data bus is going to define the pointer size, and the number of gates built into the ALU is going to define the real native data word.
I suppose it is also possible that instead of bytes computers change to using bit streams because all of the data transport changes over to high-speed 1-bit serial. I am not quite sure how that would work, exactly, but I could imagine it.
Posted Aug 8, 2014 3:41 UTC (Fri)
by jstultz (subscriber, #212)
[Link]
Posted Aug 9, 2014 11:21 UTC (Sat)
by Thue (guest, #14277)
[Link] (5 responses)
It seems unlikely to me that 128 bit general purpose architectures will be built. There are simply so few places that need 128 bit integers that it is more efficient to emulate them when needed, like GCC's current __int128_t. And for addressing, 64 bit should be enough.
Posted Aug 9, 2014 16:40 UTC (Sat)
by Cyberax (✭ supporter ✭, #52523)
[Link] (4 responses)
2^128 seems to be safe, on the other hand. It's just not feasible to fill that much RAM with a classic computer.
Posted Aug 11, 2014 13:38 UTC (Mon)
by robbe (guest, #16131)
[Link] (3 responses)
If Moore's law holds for the next 50 years, we will see computers exhausting 64bit address space by then.
So we may run out of bits before we run out of fossile fuel to power this monsters.
Posted Aug 11, 2014 14:46 UTC (Mon)
by Cyberax (✭ supporter ✭, #52523)
[Link] (2 responses)
As far as I remember, filling 2^64 bits requires _at_ _minimum_ enough energy to boil 10 liters of water. So these computers are definitely not going to be environment-friendly.
Posted Aug 11, 2014 18:13 UTC (Mon)
by dlang (guest, #313)
[Link]
There's no amount of power usage that's automatically "environmentally unfriendly"
Posted Aug 17, 2014 18:03 UTC (Sun)
by Jandar (subscriber, #85683)
[Link]
I recall reading in a paper that there is no lower energy limit to *filling* memory, but there is a lower energy limit to *clear* memory since clearing restores order thus lowers entropy. Maybe with enough bits we can skip clearing and save energy with write-once memory :-).
Posted Aug 7, 2014 15:49 UTC (Thu)
by troglobit (subscriber, #39178)
[Link]
I'm truly glad this is finally being addressed. People tend to only look to their desktop computers, or their phones being upgraded to use 64-bit processors, but the reality is that there's a HUGE embedded market going steady with 32-bit. And this will likely not change that much in the coming years.
The community has my deepest regards today, thank you so much! :)
Posted Aug 8, 2014 14:15 UTC (Fri)
by nix (subscriber, #2304)
[Link]
Posted Aug 8, 2014 16:36 UTC (Fri)
by josh (subscriber, #17465)
[Link] (3 responses)
Posted Aug 9, 2014 4:01 UTC (Sat)
by jstultz (subscriber, #212)
[Link] (2 responses)
Secondly, timespecs are desired because quite often folks really just want seconds, not nanoseconds, so we internally in the kernel have to keep both ktime_t and timespec style structures for performance reasons.
Finally, depending on how we do the userspace interface changes, we may want to try to allow applications to possibly just be re-compiled to gain 2038 support, instead of requiring developers to rework the application to use new types. So preserving the timespec style will be important here. (Granted, this won't solve all the places applications store time in non-time_t related structures, but likely will go a long way.)
Posted Aug 14, 2014 19:29 UTC (Thu)
by spitzak (guest, #4593)
[Link] (1 responses)
I sure don't like the idea that the timestruct is going to be 12 bytes rather than a power of 2.
A fixed-point system would be better, 1 sign bit + 33 integer bits + 30 bits fraction. That is in units of 1/1073741824 second, allowing all nanoseconds to have unique values. And if will be good until the year 2242. And it would use 8 bytes, the same size as the current structure.
Posted Aug 14, 2014 19:49 UTC (Thu)
by jwakely (subscriber, #60262)
[Link]
> The 64-bit timestamp format is used in packet headers and other places with limited word size. It includes a 32-bit unsigned seconds field spanning 136 years and a 32-bit fraction field resolving 232 picoseconds.
Posted Aug 13, 2014 22:17 UTC (Wed)
by rbthomas (subscriber, #39239)
[Link] (2 responses)
1) it's fast on modern processors (even on fixed-point embedded processors there are highly optimized macros to perform floating point arithmetic)
2) It's "fail-soft" in that there is a trade-off between precision and larger numbers. It would give micro-second resolution for about 147 years before or after the epoch and milli-second resolution for 147,000 years, nano-second resolution for about 52 days, and pico-second resolution for a little over an hour.
If the epoch is the normal UNIX epoch of Jan 1, 1970, we would have micro-second resolution on timestamps between 1823 and 2117.
For time measurements that require nano- or pico- second resolution, you can define the epoch to be anything you want as long as you can measure it with that resolution. So if I set the epoch for a given set of computations to be the present moment, I can represent measurements over a period of 104 days at nanosecond or better resolution.
Posted Aug 14, 2014 9:01 UTC (Thu)
by etienne (guest, #25256)
[Link]
Because that would mean managing floating point in the kernel, and that would mean saving/restoring the floating point registers at each task switch - instead of only when they have been used by the user-mode task...
Posted Aug 14, 2014 12:09 UTC (Thu)
by JGR (subscriber, #93631)
[Link]
Being able to change the epoch at will, and being able to regularly update the clock with small increment ticks, imply storing the "master" value in some other higher-precision format, in which case you might as well just use that for everything.
Year 2038 preparations in 3.17
One of the first changes merged for 3.17 is to simply get rid of the non-scalar form of ktime_t and force all architectures to use the 64-bit nanosecond count representation.
If my arithmetic is correct, that pushes the kernel time problem to December of 2554. I suppose I can't realistically complain about that being short-sighted, though I might have preferred having all architectures go to the non-scalar representation with 32 bit nanoseconds and 64 bit seconds, or even 64 bit attoseconds and 64 bit seconds. It's a shame that there isn't a uint128_t in the C standard.
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Great news for all of us using Linux in embedded!
ranking up to 30 years (!) -- not kidding. Some of us have tried to bring this issue up in the past, only to be shot down as proposing "band aid solutions".
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17
Year 2038 preparations in 3.17 - why not use floating point?
Year 2038 preparations in 3.17 - why not use floating point?
Year 2038 preparations in 3.17 - why not use floating point?
Migrating to floating point would be far more painful than bumping an integer from 32 to 64 bits.