diff options
| -rw-r--r-- | include/linux/hrtimer.h | 7 | ||||
| -rw-r--r-- | include/linux/thread_info.h | 2 | ||||
| -rw-r--r-- | kernel/hrtimer.c | 29 | ||||
| -rw-r--r-- | kernel/posix-cpu-timers.c | 4 | ||||
| -rw-r--r-- | kernel/posix-timers.c | 2 | ||||
| -rw-r--r-- | kernel/time/alarmtimer.c | 4 | 
6 files changed, 29 insertions, 19 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cc5f5f51db1..771c95802ed 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -143,7 +143,8 @@ struct hrtimer_sleeper {   */  struct hrtimer_clock_base {  	struct hrtimer_cpu_base	*cpu_base; -	clockid_t		index; +	int			index; +	clockid_t		clockid;  	struct timerqueue_head	active;  	ktime_t			resolution;  	ktime_t			(*get_time)(void); @@ -162,7 +163,7 @@ enum  hrtimer_base_type {   * struct hrtimer_cpu_base - the per cpu clock bases   * @lock:		lock protecting the base and associated clock bases   *			and timers - * @clock_base:		array of clock bases for this cpu + * @active_bases:	Bitfield to mark bases with active timers   * @expires_next:	absolute time of the next event which was scheduled   *			via clock_set_next_event()   * @hres_active:	State of high resolution mode @@ -171,9 +172,11 @@ enum  hrtimer_base_type {   * @nr_retries:		Total number of hrtimer interrupt retries   * @nr_hangs:		Total number of hrtimer interrupt hangs   * @max_hang_time:	Maximum time spent in hrtimer_interrupt + * @clock_base:		array of clock bases for this cpu   */  struct hrtimer_cpu_base {  	raw_spinlock_t			lock; +	unsigned long			active_bases;  #ifdef CONFIG_HIGH_RES_TIMERS  	ktime_t				expires_next;  	int				hres_active; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 20fc303947d..8d03f079688 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -29,7 +29,7 @@ struct restart_block {  		} futex;  		/* For nanosleep */  		struct { -			clockid_t index; +			clockid_t clockid;  			struct timespec __user *rmtp;  #ifdef CONFIG_COMPAT  			struct compat_timespec __user *compat_rmtp; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 26dd32f9f6b..1b08f6d67f1 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -64,17 +64,20 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =  	.clock_base =  	{  		{ -			.index = CLOCK_REALTIME, +			.index = HRTIMER_BASE_REALTIME, +			.clockid = CLOCK_REALTIME,  			.get_time = &ktime_get_real,  			.resolution = KTIME_LOW_RES,  		},  		{ -			.index = CLOCK_MONOTONIC, +			.index = HRTIMER_BASE_MONOTONIC, +			.clockid = CLOCK_MONOTONIC,  			.get_time = &ktime_get,  			.resolution = KTIME_LOW_RES,  		},  		{ -			.index = CLOCK_BOOTTIME, +			.index = HRTIMER_BASE_BOOTTIME, +			.clockid = CLOCK_BOOTTIME,  			.get_time = &ktime_get_boottime,  			.resolution = KTIME_LOW_RES,  		}, @@ -196,7 +199,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,  	struct hrtimer_cpu_base *new_cpu_base;  	int this_cpu = smp_processor_id();  	int cpu = hrtimer_get_target(this_cpu, pinned); -	int basenum = hrtimer_clockid_to_base(base->index); +	int basenum = base->index;  again:  	new_cpu_base = &per_cpu(hrtimer_bases, cpu); @@ -857,6 +860,7 @@ static int enqueue_hrtimer(struct hrtimer *timer,  	debug_activate(timer);  	timerqueue_add(&base->active, &timer->node); +	base->cpu_base->active_bases |= 1 << base->index;  	/*  	 * HRTIMER_STATE_ENQUEUED is or'ed to the current state to preserve the @@ -898,6 +902,8 @@ static void __remove_hrtimer(struct hrtimer *timer,  #endif  	}  	timerqueue_del(&base->active, &timer->node); +	if (!timerqueue_getnext(&base->active)) +		base->cpu_base->active_bases &= ~(1 << base->index);  out:  	timer->state = newstate;  } @@ -1235,7 +1241,6 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)  void hrtimer_interrupt(struct clock_event_device *dev)  {  	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases); -	struct hrtimer_clock_base *base;  	ktime_t expires_next, now, entry_time, delta;  	int i, retries = 0; @@ -1257,12 +1262,15 @@ retry:  	 */  	cpu_base->expires_next.tv64 = KTIME_MAX; -	base = cpu_base->clock_base; -  	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) { -		ktime_t basenow; +		struct hrtimer_clock_base *base;  		struct timerqueue_node *node; +		ktime_t basenow; + +		if (!(cpu_base->active_bases & (1 << i))) +			continue; +		base = cpu_base->clock_base + i;  		basenow = ktime_add(now, base->offset);  		while ((node = timerqueue_getnext(&base->active))) { @@ -1295,7 +1303,6 @@ retry:  			__run_hrtimer(timer, &basenow);  		} -		base++;  	}  	/* @@ -1526,7 +1533,7 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart)  	struct timespec __user  *rmtp;  	int ret = 0; -	hrtimer_init_on_stack(&t.timer, restart->nanosleep.index, +	hrtimer_init_on_stack(&t.timer, restart->nanosleep.clockid,  				HRTIMER_MODE_ABS);  	hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); @@ -1578,7 +1585,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp,  	restart = ¤t_thread_info()->restart_block;  	restart->fn = hrtimer_nanosleep_restart; -	restart->nanosleep.index = t.timer.base->index; +	restart->nanosleep.clockid = t.timer.base->clockid;  	restart->nanosleep.rmtp = rmtp;  	restart->nanosleep.expires = hrtimer_get_expires_tv64(&t.timer); diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 0791b13df7b..58f405b581e 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -1514,7 +1514,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,  			return -EFAULT;  		restart_block->fn = posix_cpu_nsleep_restart; -		restart_block->nanosleep.index = which_clock; +		restart_block->nanosleep.clockid = which_clock;  		restart_block->nanosleep.rmtp = rmtp;  		restart_block->nanosleep.expires = timespec_to_ns(rqtp);  	} @@ -1523,7 +1523,7 @@ static int posix_cpu_nsleep(const clockid_t which_clock, int flags,  static long posix_cpu_nsleep_restart(struct restart_block *restart_block)  { -	clockid_t which_clock = restart_block->nanosleep.index; +	clockid_t which_clock = restart_block->nanosleep.clockid;  	struct timespec t;  	struct itimerspec it;  	int error; diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index e5498d7405c..a1b5edf1bf9 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -1056,7 +1056,7 @@ SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags,   */  long clock_nanosleep_restart(struct restart_block *restart_block)  { -	clockid_t which_clock = restart_block->nanosleep.index; +	clockid_t which_clock = restart_block->nanosleep.clockid;  	struct k_clock *kc = clockid_to_kclock(which_clock);  	if (WARN_ON_ONCE(!kc || !kc->nsleep_restart)) diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index c6027fe9a4e..2d966244ea6 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -494,7 +494,7 @@ static int update_rmtp(ktime_t exp, enum  alarmtimer_type type,   */  static long __sched alarm_timer_nsleep_restart(struct restart_block *restart)  { -	enum  alarmtimer_type type = restart->nanosleep.index; +	enum  alarmtimer_type type = restart->nanosleep.clockid;  	ktime_t exp;  	struct timespec __user  *rmtp;  	struct alarm alarm; @@ -573,7 +573,7 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,  	restart = ¤t_thread_info()->restart_block;  	restart->fn = alarm_timer_nsleep_restart; -	restart->nanosleep.index = type; +	restart->nanosleep.clockid = type;  	restart->nanosleep.expires = exp.tv64;  	restart->nanosleep.rmtp = rmtp;  	ret = -ERESTART_RESTARTBLOCK;  |