From: Oliver Hartkopp Date: Wed, 18 Jan 2017 20:30:51 +0000 (+0100) Subject: can: bcm: fix hrtimer/tasklet termination in bcm op removal X-Git-Tag: v3.10.107~237 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5361ee850ef3e69a92883e46ccbb5ed6ccb9323;p=thirdparty%2Fkernel%2Fstable.git can: bcm: fix hrtimer/tasklet termination in bcm op removal commit a06393ed03167771246c4c43192d9c264bc48412 upstream. When removing a bcm tx operation either a hrtimer or a tasklet might run. As the hrtimer triggers its associated tasklet and vice versa we need to take care to mutually terminate both handlers. Reported-by: Michael Josenhans Signed-off-by: Oliver Hartkopp Tested-by: Michael Josenhans Signed-off-by: Marc Kleine-Budde Signed-off-by: Willy Tarreau --- diff --git a/net/can/bcm.c b/net/can/bcm.c index 725ce812cfbc3..6e0a88d9c554b 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -706,14 +706,23 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, canid_t can_id, static void bcm_remove_op(struct bcm_op *op) { - hrtimer_cancel(&op->timer); - hrtimer_cancel(&op->thrtimer); - - if (op->tsklet.func) - tasklet_kill(&op->tsklet); + if (op->tsklet.func) { + while (test_bit(TASKLET_STATE_SCHED, &op->tsklet.state) || + test_bit(TASKLET_STATE_RUN, &op->tsklet.state) || + hrtimer_active(&op->timer)) { + hrtimer_cancel(&op->timer); + tasklet_kill(&op->tsklet); + } + } - if (op->thrtsklet.func) - tasklet_kill(&op->thrtsklet); + if (op->thrtsklet.func) { + while (test_bit(TASKLET_STATE_SCHED, &op->thrtsklet.state) || + test_bit(TASKLET_STATE_RUN, &op->thrtsklet.state) || + hrtimer_active(&op->thrtimer)) { + hrtimer_cancel(&op->thrtimer); + tasklet_kill(&op->thrtsklet); + } + } if ((op->frames) && (op->frames != &op->sframe)) kfree(op->frames);