diff options
Diffstat (limited to 'kernel/time/timer.c')
| -rw-r--r-- | kernel/time/timer.c | 10 | 
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c index af1c08b0b168..9abc41715fd2 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1526,6 +1526,7 @@ static unsigned long __next_timer_interrupt(struct timer_base *base)  	clk = base->clk;  	for (lvl = 0; lvl < LVL_DEPTH; lvl++, offset += LVL_SIZE) {  		int pos = next_pending_bucket(base, offset, clk & LVL_MASK); +		unsigned long lvl_clk = clk & LVL_CLK_MASK;  		if (pos >= 0) {  			unsigned long tmp = clk + (unsigned long) pos; @@ -1533,6 +1534,13 @@ static unsigned long __next_timer_interrupt(struct timer_base *base)  			tmp <<= LVL_SHIFT(lvl);  			if (time_before(tmp, next))  				next = tmp; + +			/* +			 * If the next expiration happens before we reach +			 * the next level, no need to check further. +			 */ +			if (pos <= ((LVL_CLK_DIV - lvl_clk) & LVL_CLK_MASK)) +				break;  		}  		/*  		 * Clock for the next level. If the current level clock lower @@ -1570,7 +1578,7 @@ static unsigned long __next_timer_interrupt(struct timer_base *base)  		 * So the simple check whether the lower bits of the current  		 * level are 0 or not is sufficient for all cases.  		 */ -		adj = clk & LVL_CLK_MASK ? 1 : 0; +		adj = lvl_clk ? 1 : 0;  		clk >>= LVL_CLK_SHIFT;  		clk += adj;  	}  | 
