Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.sao.ru/hq/sts/linux/doc/porting_to_26/22808.html
Дата изменения: Unknown
Дата индексирования: Tue Oct 2 16:41:35 2012
Кодировка:

Поисковые слова: п п п п п п п п п п п п п
LWN: Driver porting: Timekeeping changes
LWN.net Logo

 


 
Summary page
Return to the Kernel page
 
Recent Features

LWN.net Weekly Edition for March 18, 2004

LWN.net Weekly Edition for March 11, 2004

The annotated SCO stock price chart

A grumpy editor's calendar search

LWN.net Weekly Edition for March 4, 2004

Printable page
 

 

Driver porting: Timekeeping changes

This article is part of the LWN Porting Drivers to 2.6 series.
One might be tempted to think that the basic task of keeping track of the time would not change that much from one kernel to the next. And, in fact, most kernel code which worries about times (and time intervals) will likely work unchanged in the 2.6 kernel. Code which gets into the details of how the kernel manages time may well need to adapt to some changes, however.

Internal clock frequency

One change which shouldn't be problematic for most code is the change in the internal clock rate on the x86 architecture. In previous kernels, HZ was 100; in 2.6 it has been bumped up to 1000. If your code makes any assumptions about what HZ really was (or, by extension, what jiffies really signified), you may have to make some changes now. For what it's worth, as of 2.6.0-test9, the default values of HZ in the mainline kernel source (which sometimes lags the architecture-specific trees) is as follows: Alpha: 1024/1200; ARM: 100/128/200/1000; CRIS: 100; i386: 1000; IA-64: 1024; M68K: 100; M68K-nommu: 50-1000; MIPS: 100/128/1000; MIPS64: 100; PA-RISC: 100/1000; PowerPC32: 100; PowerPC64: 1000; S/390: 100; SPARC32: 100; SPARC64: 100; SuperH: 100/1000; UML: 100; v850: 24-100; x86-64: 1000.

Kernel time variables

When the internal clock rate on a 32-bit system is set to 1000, the classic 32-bit jiffies variable will overflow in just over 49 days. Overflows could always happen on systems with a long uptime, but, when it took well over a year of uptime, it was a relatively rare occurrence - even on Linux systems. It is not uncommon at all, however, for a system to be up for more than 50 days. In most cases, having jiffies wrap around is not a real problem; it can be inconvenient for tasks like process accounting, however. So the 2.5 kernel has a new counter called jiffies_64. With 64 bits to work with, jiffies_64 will not wrap around in a time frame that need concern most of us - at least until some future kernel starts using a gigahertz internal clock.

For what it's worth, on most architectures, the classic, 32-bit jiffies variable is now just the least significant half of jiffies_64.

Note that, on 32-bit systems, a 64-bit jiffies value raises concurrency issues. It is deliberately not declared as a volatile value (for performance reasons), so the possibility exists that code like:

    u64 my_time = jiffies_64;

could get an inconsistent version of the variable, where the top and bottom halves do not match. To avoid this possibility, code accessing jiffies_64 should use xtime_lock, which is the new seqlock type as of 2.5.60. In most cases, though, it will be easier to just use the convenience function provided by the kernel:

    #include <linux/jiffies.h>

    u64 my_time = get_jiffies_64();

Users of the internal xtime variable will notice a couple of similar changes. One is that xtime, too, is now protected by xtime_lock (as it is in 2.4 as of 2.4.10), so any code which plays around with disabling interrupts or such before accessing xtime will need to change. The best solution is probably to use:

    struct timespec current_kernel_time(void);

which takes care of locking for you. xtime also now is a struct timespec rather than struct timeval; the difference being that the sub-second part is called tv_nsec, and is in nanoseconds.

Timers

The kernel timer interface is essentially unchanged since 2.4, with one exception. The new function:

    void add_timer_on(struct timer_list *timer, int cpu);

will cause the timer function to run on the given CPU with the expiration time hits.

Delays

The 2.5 kernel includes a new macro ndelay(), which delays for a given number of nanoseconds. It can be useful for interactions with hardware which insists on very short delays between operations. On most architectures, however, ndelay(n) is equal to udelay(1) for waits of less than one microsecond.

POSIX clocks

The POSIX clocks patch (merged into 2.5.63) is beyond the scope of this article. If you are working with a device which can provide an interesting time service (high resolution or high accuracy), you may want to consider using it to drive a POSIX clock. Look into kernel/posix-timers.c for more information.
Post a comment

  Driver porting: Timekeeping changes
(Posted Feb 27, 2003 9:13 UTC (Thu) by ekj) (Post reply)

With 64 bits to work with, jiffies_64 will not wrap around in a time frame that need concern most of us - at least until some future kernel starts using a gigahertz internal clock.

Actually, even with a Ghz internal clock a 64-bit counter will still need about 600 years before it ticks over. Even with a 100Ghz internal clock we will experience wrap-around only once every 6 years. Few systems stay up that long.

  Driver porting: Timekeeping changes
(Posted Feb 27, 2003 19:59 UTC (Thu) by cpeterso) (Post reply)


Someone posted a patch on LKML a few years ago and again recently, that started jiffies at -5 minutes instead of 0. That is, the patch would force a jiffy wraparound 5 minutes after boot, every time for all systems. Kernel and driver wraparound bugs would have to be fixed.

Does anyone know if there are plans to merge this in Linux 2.5?

Copyright (©) 2003, Eklektix, Inc.
Linux (®) is a registered trademark of Linus Torvalds
Powered by Rackspace Managed Hosting.