Currently oz_timer_add sets the new expiry time before calling
hrtimer_start_expires where the timer is actually updated in the
timerqueue.
However, this update to expiry time is racy because the the
hrtimer_set_expires call is being performed from a softirq or a thread's
context. The CPU could recieve a hrtimer_interrupt before the
hrtimer_start_expires call but after hrtimer_set_expires.
This would leave the hrtimer with a new expiry value but with the same
position in the rbtree which a subsequent hrtimer_interrupt could use
to perform its timerqueue add/del operations with. Leaving the rbtree
in this stale/bad state causes some timers to never get serviced.
Fix this by first removing the timer from the timerqueue by calling
hrtimer_cancel and then updating the expiry time.
Bug
200016188
Change-Id: Ib8acb9f2977580e077bbe968a32c6deba992d000
Signed-off-by: Sai Gurrappadi <sgurrappadi@nvidia.com>
Reviewed-on: http://git-master/r/439729
(cherry picked from commit
bad282f7a9bf0cdbef32a6353e1a0154277eaaa7)
Reviewed-on: http://git-master/r/440535
GVS: Gerrit_Virtual_Submit
Reviewed-by: Mitch Luban <mluban@nvidia.com>