alarmtimer: Lock k_itimer during timer callback
Locks the k_itimer's it_lock member when handling the alarm timer's expiry callback. The regular posix timers defined in posix-timers.c have this lock held during timout processing because their callbacks are routed through posix_timer_fn(). The alarm timers follow a different path, so they ought to grab the lock somewhere else. Cc: stable@vger.kernel.org Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@kernel.org> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Sharvil Nanavati <sharvil@google.com> Signed-off-by: Richard Larocque <rlarocque@google.com> Signed-off-by: John Stultz <john.stultz@linaro.org>
This commit is contained in:
parent
265b81d23a
commit
474e941bed
|
@ -464,8 +464,12 @@ 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;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ptr->it_lock, flags);
|
||||||
if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
|
if ((ptr->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) {
|
||||||
if (posix_timer_event(ptr, 0) != 0)
|
if (posix_timer_event(ptr, 0) != 0)
|
||||||
ptr->it_overrun++;
|
ptr->it_overrun++;
|
||||||
|
@ -475,9 +479,11 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
|
||||||
if (ptr->it.alarm.interval.tv64) {
|
if (ptr->it.alarm.interval.tv64) {
|
||||||
ptr->it_overrun += alarm_forward(alarm, now,
|
ptr->it_overrun += alarm_forward(alarm, now,
|
||||||
ptr->it.alarm.interval);
|
ptr->it.alarm.interval);
|
||||||
return ALARMTIMER_RESTART;
|
result = ALARMTIMER_RESTART;
|
||||||
}
|
}
|
||||||
return ALARMTIMER_NORESTART;
|
spin_unlock_irqrestore(&ptr->it_lock, flags);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue