mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-06 16:49:22 +00:00
alarmtimer: Switch over to generic set/get/rearm routine
All required callbacks are in place. Switch the alarm timer based posix interval timer callbacks to the common implementation and remove the incorrect private implementation. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: John Stultz <john.stultz@linaro.org> Link: http://lkml.kernel.org/r/20170530211657.825471962@linutronix.de
This commit is contained in:
parent
b3bf6f369d
commit
f2c45807d3
3 changed files with 29 additions and 110 deletions
|
@ -515,20 +515,26 @@ static enum alarmtimer_type clock2alarm(clockid_t clockid)
|
||||||
static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
|
static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
|
||||||
ktime_t now)
|
ktime_t now)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
struct k_itimer *ptr = container_of(alarm, struct k_itimer,
|
struct k_itimer *ptr = container_of(alarm, struct k_itimer,
|
||||||
it.alarm.alarmtimer);
|
it.alarm.alarmtimer);
|
||||||
enum alarmtimer_restart result = ALARMTIMER_NORESTART;
|
enum alarmtimer_restart result = ALARMTIMER_NORESTART;
|
||||||
|
unsigned long flags;
|
||||||
|
int si_private = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&ptr->it_lock, flags);
|
spin_lock_irqsave(&ptr->it_lock, flags);
|
||||||
if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
|
|
||||||
if (posix_timer_event(ptr, 0))
|
|
||||||
ptr->it_overrun++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Re-add periodic timers */
|
ptr->it_active = 0;
|
||||||
if (ptr->it_interval) {
|
if (ptr->it_interval)
|
||||||
ptr->it_overrun += alarm_forward(alarm, now, ptr->it_interval);
|
si_private = ++ptr->it_requeue_pending;
|
||||||
|
|
||||||
|
if (posix_timer_event(ptr, si_private) && ptr->it_interval) {
|
||||||
|
/*
|
||||||
|
* Handle ignored signals and rearm the timer. This will go
|
||||||
|
* away once we handle ignored signals proper.
|
||||||
|
*/
|
||||||
|
ptr->it_overrun += alarm_forward_now(alarm, ptr->it_interval);
|
||||||
|
++ptr->it_requeue_pending;
|
||||||
|
ptr->it_active = 1;
|
||||||
result = ALARMTIMER_RESTART;
|
result = ALARMTIMER_RESTART;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ptr->it_lock, flags);
|
spin_unlock_irqrestore(&ptr->it_lock, flags);
|
||||||
|
@ -658,97 +664,6 @@ static int alarm_timer_create(struct k_itimer *new_timer)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* alarm_timer_get - posix timer_get interface
|
|
||||||
* @timr: k_itimer pointer
|
|
||||||
* @cur_setting: itimerspec data to fill
|
|
||||||
*
|
|
||||||
* Copies out the current itimerspec data
|
|
||||||
*/
|
|
||||||
static void alarm_timer_get(struct k_itimer *timr,
|
|
||||||
struct itimerspec64 *cur_setting)
|
|
||||||
{
|
|
||||||
ktime_t relative_expiry_time =
|
|
||||||
alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
|
|
||||||
|
|
||||||
if (ktime_to_ns(relative_expiry_time) > 0) {
|
|
||||||
cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
|
|
||||||
} else {
|
|
||||||
cur_setting->it_value.tv_sec = 0;
|
|
||||||
cur_setting->it_value.tv_nsec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_setting->it_interval = ktime_to_timespec64(timr->it_interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* alarm_timer_del - posix timer_del interface
|
|
||||||
* @timr: k_itimer pointer to be deleted
|
|
||||||
*
|
|
||||||
* Cancels any programmed alarms for the given timer.
|
|
||||||
*/
|
|
||||||
static int alarm_timer_del(struct k_itimer *timr)
|
|
||||||
{
|
|
||||||
if (!rtcdev)
|
|
||||||
return -ENOTSUPP;
|
|
||||||
|
|
||||||
if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
|
|
||||||
return TIMER_RETRY;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* alarm_timer_set - posix timer_set interface
|
|
||||||
* @timr: k_itimer pointer to be deleted
|
|
||||||
* @flags: timer flags
|
|
||||||
* @new_setting: itimerspec to be used
|
|
||||||
* @old_setting: itimerspec being replaced
|
|
||||||
*
|
|
||||||
* Sets the timer to new_setting, and starts the timer.
|
|
||||||
*/
|
|
||||||
static int alarm_timer_set(struct k_itimer *timr, int flags,
|
|
||||||
struct itimerspec64 *new_setting,
|
|
||||||
struct itimerspec64 *old_setting)
|
|
||||||
{
|
|
||||||
ktime_t exp;
|
|
||||||
|
|
||||||
if (!rtcdev)
|
|
||||||
return -ENOTSUPP;
|
|
||||||
|
|
||||||
if (flags & ~TIMER_ABSTIME)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (old_setting)
|
|
||||||
alarm_timer_get(timr, old_setting);
|
|
||||||
|
|
||||||
/* If the timer was already set, cancel it */
|
|
||||||
if (alarm_try_to_cancel(&timr->it.alarm.alarmtimer) < 0)
|
|
||||||
return TIMER_RETRY;
|
|
||||||
|
|
||||||
/* start the timer */
|
|
||||||
timr->it_interval = timespec64_to_ktime(new_setting->it_interval);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Rate limit to the tick as a hot fix to prevent DOS. Will be
|
|
||||||
* mopped up later.
|
|
||||||
*/
|
|
||||||
if (timr->it_interval < TICK_NSEC)
|
|
||||||
timr->it_interval = TICK_NSEC;
|
|
||||||
|
|
||||||
exp = timespec64_to_ktime(new_setting->it_value);
|
|
||||||
/* Convert (if necessary) to absolute time */
|
|
||||||
if (flags != TIMER_ABSTIME) {
|
|
||||||
ktime_t now;
|
|
||||||
|
|
||||||
now = alarm_bases[timr->it.alarm.alarmtimer.type].gettime();
|
|
||||||
exp = ktime_add_safe(now, exp);
|
|
||||||
}
|
|
||||||
|
|
||||||
alarm_start(&timr->it.alarm.alarmtimer, exp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
|
* alarmtimer_nsleep_wakeup - Wakeup function for alarm_timer_nsleep
|
||||||
* @alarm: ptr to alarm that fired
|
* @alarm: ptr to alarm that fired
|
||||||
|
@ -926,9 +841,9 @@ const struct k_clock alarm_clock = {
|
||||||
.clock_getres = alarm_clock_getres,
|
.clock_getres = alarm_clock_getres,
|
||||||
.clock_get = alarm_clock_get,
|
.clock_get = alarm_clock_get,
|
||||||
.timer_create = alarm_timer_create,
|
.timer_create = alarm_timer_create,
|
||||||
.timer_set = alarm_timer_set,
|
.timer_set = common_timer_set,
|
||||||
.timer_del = alarm_timer_del,
|
.timer_del = common_timer_del,
|
||||||
.timer_get = alarm_timer_get,
|
.timer_get = common_timer_get,
|
||||||
.timer_arm = alarm_timer_arm,
|
.timer_arm = alarm_timer_arm,
|
||||||
.timer_rearm = alarm_timer_rearm,
|
.timer_rearm = alarm_timer_rearm,
|
||||||
.timer_forward = alarm_timer_forward,
|
.timer_forward = alarm_timer_forward,
|
||||||
|
|
|
@ -637,8 +637,7 @@ static int common_hrtimer_forward(struct k_itimer *timr, ktime_t now)
|
||||||
* it is the same as a requeue pending timer WRT to what we should
|
* it is the same as a requeue pending timer WRT to what we should
|
||||||
* report.
|
* report.
|
||||||
*/
|
*/
|
||||||
static void
|
void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
|
||||||
common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
|
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = timr->kclock;
|
const struct k_clock *kc = timr->kclock;
|
||||||
ktime_t now, remaining, iv;
|
ktime_t now, remaining, iv;
|
||||||
|
@ -768,8 +767,7 @@ static int common_hrtimer_try_to_cancel(struct k_itimer *timr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set a POSIX.1b interval timer. */
|
/* Set a POSIX.1b interval timer. */
|
||||||
static int
|
int common_timer_set(struct k_itimer *timr, int flags,
|
||||||
common_timer_set(struct k_itimer *timr, int flags,
|
|
||||||
struct itimerspec64 *new_setting,
|
struct itimerspec64 *new_setting,
|
||||||
struct itimerspec64 *old_setting)
|
struct itimerspec64 *old_setting)
|
||||||
{
|
{
|
||||||
|
@ -855,7 +853,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags,
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int common_timer_del(struct k_itimer *timer)
|
int common_timer_del(struct k_itimer *timer)
|
||||||
{
|
{
|
||||||
const struct k_clock *kc = timer->kclock;
|
const struct k_clock *kc = timer->kclock;
|
||||||
|
|
||||||
|
|
|
@ -33,3 +33,9 @@ extern const struct k_clock clock_thread;
|
||||||
extern const struct k_clock alarm_clock;
|
extern const struct k_clock alarm_clock;
|
||||||
|
|
||||||
int posix_timer_event(struct k_itimer *timr, int si_private);
|
int posix_timer_event(struct k_itimer *timr, int si_private);
|
||||||
|
|
||||||
|
void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting);
|
||||||
|
int common_timer_set(struct k_itimer *timr, int flags,
|
||||||
|
struct itimerspec64 *new_setting,
|
||||||
|
struct itimerspec64 *old_setting);
|
||||||
|
int common_timer_del(struct k_itimer *timer);
|
||||||
|
|
Loading…
Reference in a new issue