mirror of
https://github.com/openvswitch/ovs
synced 2025-08-29 05:18:13 +00:00
97 lines
3.1 KiB
C
97 lines
3.1 KiB
C
#ifndef __LINUX_TIMER_WRAPPER_H
|
|
#define __LINUX_TIMER_WRAPPER_H 1
|
|
|
|
#include_next <linux/timer.h>
|
|
|
|
#include <linux/version.h>
|
|
|
|
#ifndef RHEL_RELEASE_VERSION
|
|
#define RHEL_RELEASE_VERSION(X,Y) ( 0 )
|
|
#endif
|
|
#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) && \
|
|
(!defined(RHEL_RELEASE_CODE) || \
|
|
(RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,1))))
|
|
|
|
extern unsigned long volatile jiffies;
|
|
|
|
/**
|
|
* __round_jiffies - function to round jiffies to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
* @cpu: the processor number on which the timeout will happen
|
|
*
|
|
* __round_jiffies() rounds an absolute time in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The exact rounding is skewed for each processor to avoid all
|
|
* processors firing at the exact same time, which could lead
|
|
* to lock contention or spurious cache line bouncing.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
static inline unsigned long __round_jiffies(unsigned long j, int cpu)
|
|
{
|
|
int rem;
|
|
unsigned long original = j;
|
|
|
|
/*
|
|
* We don't want all cpus firing their timers at once hitting the
|
|
* same lock or cachelines, so we skew each extra cpu with an extra
|
|
* 3 jiffies. This 3 jiffies came originally from the mm/ code which
|
|
* already did this.
|
|
* The skew is done by adding 3*cpunr, then round, then subtract this
|
|
* extra offset again.
|
|
*/
|
|
j += cpu * 3;
|
|
|
|
rem = j % HZ;
|
|
|
|
/*
|
|
* If the target jiffie is just after a whole second (which can happen
|
|
* due to delays of the timer irq, long irq off times etc etc) then
|
|
* we should round down to the whole second, not up. Use 1/4th second
|
|
* as cutoff for this rounding as an extreme upper bound for this.
|
|
*/
|
|
if (rem < HZ/4) /* round down */
|
|
j = j - rem;
|
|
else /* round up */
|
|
j = j - rem + HZ;
|
|
|
|
/* now that we have rounded, subtract the extra skew again */
|
|
j -= cpu * 3;
|
|
|
|
if (j <= jiffies) /* rounding ate our timeout entirely; */
|
|
return original;
|
|
return j;
|
|
}
|
|
|
|
|
|
/**
|
|
* round_jiffies - function to round jiffies to a full second
|
|
* @j: the time in (absolute) jiffies that should be rounded
|
|
*
|
|
* round_jiffies() rounds an absolute time in the future (in jiffies)
|
|
* up or down to (approximately) full seconds. This is useful for timers
|
|
* for which the exact time they fire does not matter too much, as long as
|
|
* they fire approximately every X seconds.
|
|
*
|
|
* By rounding these timers to whole seconds, all such timers will fire
|
|
* at the same time, rather than at various times spread out. The goal
|
|
* of this is to have the CPU wake up less, which saves power.
|
|
*
|
|
* The return value is the rounded version of the @j parameter.
|
|
*/
|
|
static inline unsigned long round_jiffies(unsigned long j)
|
|
{
|
|
return __round_jiffies(j, 0); // FIXME
|
|
}
|
|
|
|
#endif /* linux kernel < 2.6.20 */
|
|
|
|
#endif
|