Deferrable timers
Many of these timers should, in fact, run as soon as the requested period has expired. Others, however, are less important - to the point that they are not worth waking up the processor. These non-critical timeouts can run some fraction of a second later (when the processor wakes up for other reasons) and nobody will notice the difference. So it would be nice if there were a way to tell the kernel that a specific timer does not require immediate action on expiration and that the processor should not wake up for the sole purpose of handling it.
Venki Pallipadi has created such a way with the deferrable timers patch. There is just one new function added to the internal kernel API:
void init_timer_deferrable(struct timer_list *timer);
Timers which are initialized in this fashion will be recognized as deferrable by the kernel. They will not be considered when the kernel makes its "when should the next timer interrupt be?" decision. When the system is busy these timers will fire at the scheduled time. When things are idle, instead, they will simply wait until something more important wakes up the processor.
Venki appears to have gone to great length to minimize the changes required by this patch. So, in particular, the timer_list structure does not change at all. Instead, the low-order bit on an internal pointer (which is known to always be zero) is repurposed as a "deferrable" flag. The result is that the timer_list structure does not grow to support this new functionality, at the cost of requiring all code using the internal base pointer to mask out the "deferrable" bit.
The patch, as presented, only affects timers used within the kernel; no
code has been changed to actually use deferrable timers yet. There could
be potential in extending this interface somehow to user space. Our user
space remains full of applications which feel the need to wake up
frequently to check
the state of the world; these applications are a real
problem for power-limited systems. If those applications truly cannot be
fixed, perhaps they could at least indicate a willingness to wait when
nothing important is going on.
Index entries for this article | |
---|---|
Kernel | Dynamic tick |
Kernel | Timers |
Posted Mar 29, 2007 8:23 UTC (Thu)
by ldo (guest, #40946)
[Link] (4 responses)
Posted Mar 29, 2007 19:49 UTC (Thu)
by GreyWizard (guest, #1026)
[Link] (1 responses)
Posted Mar 30, 2007 21:10 UTC (Fri)
by venkip (guest, #37888)
[Link]
The current timer infrastructure and the changes done is for per CPU timers. That is each CPU looks at all the timers scheduled on it independently. So, such a pointer has to be atleast per CPU. Cost of such a pointer is that we will have to go through timer wheel to find next non-deferrable timer and more importantly, we have to have different set of interfaces for these deferrable and non-deferrable or have extra space in timer structure to indicate the nature of timer so that this pointer can be updated correctly when one non-deferrable tiemr expires.
Posted Mar 30, 2007 21:13 UTC (Fri)
by venkip (guest, #37888)
[Link]
Thing to note is that the pointers being reused are pointer to a per CPU structure that doesnt change over time. This structure is allocated at boot time and stays same. So, risk of coming back to biting me is slightly smaller :-)
Posted Mar 30, 2007 21:19 UTC (Fri)
by proski (subscriber, #104)
[Link]
I don't like using bits in pointers to carry extra information. That kind of thing comes back to bite you sooner or later.
Mask bits in pointers
Why not keep a single, system-wide pointer to the next non-deferable timer? This would have to be maintained each time such a timer fires but the cost might be comparable to all the masking and the resulting code might be easier to understand and maintain.One pointer?
One pointer?
Mask bits in pointers
Casting a pointer to unsigned int would cause at least a warning on 64-bit systems. And I'm not convinced that avoiding an extra field in struct tvec_t_base_s by using pointer arithmetics would offer any advantage either in memory requirements or in speed.
Mask bits in pointers