[tip:timers/core] rtc: Avoid setting alarm to a time in the past

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Commit-ID:  bd729d72b428261f2975360e0c117d7d7a2cd6e8
Gitweb:     http://git.kernel.org/tip/bd729d72b428261f2975360e0c117d7d7a2cd6e8
Author:     John Stultz <john.stultz@xxxxxxxxxx>
AuthorDate: Thu, 5 Jan 2012 15:21:19 -0800
Committer:  John Stultz <john.stultz@xxxxxxxxxx>
CommitDate: Thu, 26 Jan 2012 19:41:30 -0800

rtc: Avoid setting alarm to a time in the past

In some cases at boot up, the RTC alarm may be set in the past,
but still have the enabled flag on. This was causing problems,
because we would then enqueue the alarm into the timerqueue,
but it would never fire. This would clog up the timerqueue
and keep other alarms from working.

The fix is to check the alarm against the current rtc time at
boot and avoid enqueueing the alarm if it is in the past.

Reported-by: NeilBrown <neilb@xxxxxxx>
Tested-by: NeilBrown <neilb@xxxxxxx>
Tested-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx>
Signed-off-by: John Stultz <john.stultz@xxxxxxxxxx>
 drivers/rtc/interface.c |   11 ++++++++++-
 1 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 8a1c031..c55a160 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -380,18 +380,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
 int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 	int err;
+	struct rtc_time now;
 	err = rtc_valid_tm(&alarm->time);
 	if (err != 0)
 		return err;
+	err = rtc_read_time(rtc, &now);
+	if (err)
+		return err;
 	err = mutex_lock_interruptible(&rtc->ops_lock);
 	if (err)
 		return err;
 	rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
 	rtc->aie_timer.period = ktime_set(0, 0);
-	if (alarm->enabled) {
+	/* Alarm has to be enabled & in the futrure for us to enqueue it */
+	if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 <
+			 rtc->aie_timer.node.expires.tv64)) {
 		rtc->aie_timer.enabled = 1;
 		timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node);
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Linux USB Devel]     [Linux Video &Media]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Free Online Dating]     [Linux Kernel]     [Linux SCSI]     [XFree86]

Powered by Linux