]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
staging: ozwpan: Cancel hrtimer before expiry set
authorSai Gurrappadi <sgurrappadi@nvidia.com>
Fri, 18 Jul 2014 06:46:56 +0000 (23:46 -0700)
committerMitch Luban <mluban@nvidia.com>
Thu, 24 Jul 2014 17:42:03 +0000 (10:42 -0700)
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>
drivers/staging/ozwpan/ozproto.c

index 1066c4e49ad70bbec7b90cfcbdd1fb539d5e4aed..2c3b44d068787294e7a9e5816b022a56c4948857 100644 (file)
@@ -597,6 +597,7 @@ void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time)
        case OZ_TIMER_TOUT:
        case OZ_TIMER_STOP:
                if (hrtimer_active(&pd->timeout)) {
+                       hrtimer_cancel(&pd->timeout);
                        hrtimer_set_expires(&pd->timeout, ktime_set(due_time /
                        MSEC_PER_SEC, (due_time % MSEC_PER_SEC) *
                                                        NSEC_PER_MSEC));