diff options
| author | John Stultz <john.stultz@linaro.org> | 2011-08-10 10:37:59 -0700 | 
|---|---|---|
| committer | John Stultz <john.stultz@linaro.org> | 2011-08-10 14:55:20 -0700 | 
| commit | 4b41308d2d0398409620613c7eaaaf52c738b042 (patch) | |
| tree | 47a6becae6272eb9c06e57a0a9d1698b8f1811c8 | |
| parent | 6af7e471e5a7746b8024d70b4363d3dfe41d36b8 (diff) | |
| download | olio-linux-3.10-4b41308d2d0398409620613c7eaaaf52c738b042.tar.xz olio-linux-3.10-4b41308d2d0398409620613c7eaaaf52c738b042.zip  | |
alarmtimers: Change alarmtimer functions to return alarmtimer_restart values
In order to properly fix the denial of service issue with high freq
periodic alarm timers, we need to push the re-arming logic into the
alarm timer handler, much as the hrtimer code does.
This patch introduces alarmtimer_restart enum and changes the
alarmtimer handler declarations to use it as a return value. Further,
to ease following changes, it extends the alarmtimer handler functions
to also take the time at expiration. No logic is yet modified.
CC: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
| -rw-r--r-- | include/linux/alarmtimer.h | 9 | ||||
| -rw-r--r-- | kernel/time/alarmtimer.c | 13 | 
2 files changed, 16 insertions, 6 deletions
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index c5d6095b46f..0289eb29e79 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -13,6 +13,11 @@ enum alarmtimer_type {  	ALARM_NUMTYPE,  }; +enum alarmtimer_restart { +	ALARMTIMER_NORESTART, +	ALARMTIMER_RESTART, +}; +  /**   * struct alarm - Alarm timer structure   * @node:	timerqueue node for adding to the event list this value @@ -26,14 +31,14 @@ enum alarmtimer_type {  struct alarm {  	struct timerqueue_node	node;  	ktime_t			period; -	void			(*function)(struct alarm *); +	enum alarmtimer_restart	(*function)(struct alarm *, ktime_t now);  	enum alarmtimer_type	type;  	bool			enabled;  	void			*data;  };  void alarm_init(struct alarm *alarm, enum alarmtimer_type type, -		void (*function)(struct alarm *)); +		enum alarmtimer_restart (*function)(struct alarm *, ktime_t));  void alarm_start(struct alarm *alarm, ktime_t start, ktime_t period);  void alarm_cancel(struct alarm *alarm); diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index ea5e1a928d5..9e786053ffa 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -196,7 +196,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)  		}  		spin_unlock_irqrestore(&base->lock, flags);  		if (alarm->function) -			alarm->function(alarm); +			alarm->function(alarm, now);  		spin_lock_irqsave(&base->lock, flags);  	} @@ -299,7 +299,7 @@ static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)   * @function: callback that is run when the alarm fires   */  void alarm_init(struct alarm *alarm, enum alarmtimer_type type, -		void (*function)(struct alarm *)) +		enum alarmtimer_restart (*function)(struct alarm *, ktime_t))  {  	timerqueue_init(&alarm->node);  	alarm->period = ktime_set(0, 0); @@ -365,12 +365,15 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)   *   * Posix timer callback for expired alarm timers.   */ -static void alarm_handle_timer(struct alarm *alarm) +static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, +							ktime_t now)  {  	struct k_itimer *ptr = container_of(alarm, struct k_itimer,  						it.alarmtimer);  	if (posix_timer_event(ptr, 0) != 0)  		ptr->it_overrun++; + +	return ALARMTIMER_NORESTART;  }  /** @@ -509,13 +512,15 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,   *   * Wakes up the task that set the alarmtimer   */ -static void alarmtimer_nsleep_wakeup(struct alarm *alarm) +static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alarm, +								ktime_t now)  {  	struct task_struct *task = (struct task_struct *)alarm->data;  	alarm->data = NULL;  	if (task)  		wake_up_process(task); +	return ALARMTIMER_NORESTART;  }  /**  |