Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753048AbdCFJhZ (ORCPT ); Mon, 6 Mar 2017 04:37:25 -0500 Received: from mx2.suse.de ([195.135.220.15]:37229 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753150AbdCFJMw (ORCPT ); Mon, 6 Mar 2017 04:12:52 -0500 X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" From: Jiri Slaby To: stable@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Oliver Hartkopp , Marc Kleine-Budde , Jiri Slaby Subject: [PATCH 3.12 033/113] can: bcm: fix hrtimer/tasklet termination in bcm op removal Date: Mon, 6 Mar 2017 10:10:57 +0100 Message-Id: <192c10ab8c5a29f87518587f4c3f0f13353ee049.1488791430.git.jslaby@suse.cz> X-Mailer: git-send-email 2.12.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1833 Lines: 58 From: Oliver Hartkopp 3.12-stable review patch. If anyone has any objections, please let me know. =============== 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: Jiri Slaby --- net/can/bcm.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index 392a687d3ca6..e845618f53dd 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); -- 2.12.0