Hi Jeffy, On Mon, Feb 26, 2018 at 6:50 PM, Jeffy Chen <jeffy.chen@xxxxxxxxxxxxxx> wrote: > Since accessing a Chrome OS EC based rtc is a slow operation, there is a > race window where if the alarm is set for the next second and the second > ticks over right before calculating the alarm offset. > > In this case the current driver is setting a 0-second alarm, which would > be considered as disabling alarms by the EC(EC_RTC_ALARM_CLEAR). > > This breaks, e.g., hwclock which relies on RTC_UIE_ON -> > rtc_update_irq_enable(), which sets a 1-second alarm and expects it to > fire an interrupt. > > So return -ETIME when the alarm is in the past, follow __rtc_set_alarm(). > > Signed-off-by: Jeffy Chen <jeffy.chen@xxxxxxxxxxxxxx> Commit message is better. Thanks! And this is exactly what I was already testing. I still need to get through a bit more testing to ensure it has resolved all the races I saw, but it's good on several of them: Reviewed-by: Brian Norris <briannorris@xxxxxxxxxxxx> Tested-by: Brian Norris <briannorris@xxxxxxxxxxxx> > --- > > Changes in v3: > Fix alarm time comparing. > > Changes in v2: > Rewrite commit message as Brian suggested. > Check alarm time only when that alarm is enabled. > > drivers/rtc/rtc-cros-ec.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c > index f0ea6899c731..bf7ced095c94 100644 > --- a/drivers/rtc/rtc-cros-ec.c > +++ b/drivers/rtc/rtc-cros-ec.c > @@ -197,10 +197,10 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) > cros_ec_rtc->saved_alarm = (u32)alarm_time; > } else { > /* Don't set an alarm in the past. */ > - if ((u32)alarm_time < current_time) > - alarm_offset = EC_RTC_ALARM_CLEAR; > - else > - alarm_offset = (u32)alarm_time - current_time; > + if ((u32)alarm_time <= current_time) > + return -ETIME; > + > + alarm_offset = (u32)alarm_time - current_time; > } > > ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset); > -- > 2.11.0 > >