diff options
Diffstat (limited to 'kernel/hrtimer.c')
| -rw-r--r-- | kernel/hrtimer.c | 33 | 
1 files changed, 26 insertions, 7 deletions
| diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index cc47812d3fe..fd4b13b131f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -63,6 +63,7 @@  DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =  { +	.lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),  	.clock_base =  	{  		{ @@ -83,6 +84,12 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =  			.get_time = &ktime_get_boottime,  			.resolution = KTIME_LOW_RES,  		}, +		{ +			.index = HRTIMER_BASE_TAI, +			.clockid = CLOCK_TAI, +			.get_time = &ktime_get_clocktai, +			.resolution = KTIME_LOW_RES, +		},  	}  }; @@ -90,6 +97,7 @@ static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = {  	[CLOCK_REALTIME]	= HRTIMER_BASE_REALTIME,  	[CLOCK_MONOTONIC]	= HRTIMER_BASE_MONOTONIC,  	[CLOCK_BOOTTIME]	= HRTIMER_BASE_BOOTTIME, +	[CLOCK_TAI]		= HRTIMER_BASE_TAI,  };  static inline int hrtimer_clockid_to_base(clockid_t clock_id) @@ -106,8 +114,10 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)  {  	ktime_t xtim, mono, boot;  	struct timespec xts, tom, slp; +	s32 tai_offset;  	get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &slp); +	tai_offset = timekeeping_get_tai_offset();  	xtim = timespec_to_ktime(xts);  	mono = ktime_add(xtim, timespec_to_ktime(tom)); @@ -115,6 +125,8 @@ static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base)  	base->clock_base[HRTIMER_BASE_REALTIME].softirq_time = xtim;  	base->clock_base[HRTIMER_BASE_MONOTONIC].softirq_time = mono;  	base->clock_base[HRTIMER_BASE_BOOTTIME].softirq_time = boot; +	base->clock_base[HRTIMER_BASE_TAI].softirq_time = +				ktime_add(xtim,	ktime_set(tai_offset, 0));  }  /* @@ -160,7 +172,7 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,   */  static int hrtimer_get_target(int this_cpu, int pinned)  { -#ifdef CONFIG_NO_HZ +#ifdef CONFIG_NO_HZ_COMMON  	if (!pinned && get_sysctl_timer_migration() && idle_cpu(this_cpu))  		return get_nohz_timer_target();  #endif @@ -275,6 +287,10 @@ ktime_t ktime_add_ns(const ktime_t kt, u64 nsec)  	} else {  		unsigned long rem = do_div(nsec, NSEC_PER_SEC); +		/* Make sure nsec fits into long */ +		if (unlikely(nsec > KTIME_SEC_MAX)) +			return (ktime_t){ .tv64 = KTIME_MAX }; +  		tmp = ktime_set((long)nsec, rem);  	} @@ -651,8 +667,9 @@ static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)  {  	ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;  	ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; +	ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset; -	return ktime_get_update_offsets(offs_real, offs_boot); +	return ktime_get_update_offsets(offs_real, offs_boot, offs_tai);  }  /* @@ -1010,7 +1027,8 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,   * @timer:	the timer to be added   * @tim:	expiry time   * @delta_ns:	"slack" range for the timer - * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL) + * @mode:	expiry mode: absolute (HRTIMER_MODE_ABS) or + *		relative (HRTIMER_MODE_REL)   *   * Returns:   *  0 on success @@ -1027,7 +1045,8 @@ EXPORT_SYMBOL_GPL(hrtimer_start_range_ns);   * hrtimer_start - (re)start an hrtimer on the current CPU   * @timer:	the timer to be added   * @tim:	expiry time - * @mode:	expiry mode: absolute (HRTIMER_ABS) or relative (HRTIMER_REL) + * @mode:	expiry mode: absolute (HRTIMER_MODE_ABS) or + *		relative (HRTIMER_MODE_REL)   *   * Returns:   *  0 on success @@ -1106,7 +1125,7 @@ ktime_t hrtimer_get_remaining(const struct hrtimer *timer)  }  EXPORT_SYMBOL_GPL(hrtimer_get_remaining); -#ifdef CONFIG_NO_HZ +#ifdef CONFIG_NO_HZ_COMMON  /**   * hrtimer_get_next_event - get the time until next expiry event   * @@ -1309,6 +1328,8 @@ retry:  				expires = ktime_sub(hrtimer_get_expires(timer),  						    base->offset); +				if (expires.tv64 < 0) +					expires.tv64 = KTIME_MAX;  				if (expires.tv64 < expires_next.tv64)  					expires_next = expires;  				break; @@ -1642,8 +1663,6 @@ static void __cpuinit init_hrtimers_cpu(int cpu)  	struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);  	int i; -	raw_spin_lock_init(&cpu_base->lock); -  	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {  		cpu_base->clock_base[i].cpu_base = cpu_base;  		timerqueue_init_head(&cpu_base->clock_base[i].active); | 
