Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2993048AbbEOXUY (ORCPT ); Fri, 15 May 2015 19:20:24 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:43412 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1422935AbbEOXUN (ORCPT ); Fri, 15 May 2015 19:20:13 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dongsu Park , Ming Lei , Jens Axboe Subject: [PATCH 4.0 24/60] blk-mq: fix race between timeout and CPU hotplug Date: Fri, 15 May 2015 16:14:25 -0700 Message-Id: <20150515231019.551018068@linuxfoundation.org> X-Mailer: git-send-email 2.4.0 In-Reply-To: <20150515231018.815421141@linuxfoundation.org> References: <20150515231018.815421141@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2120 Lines: 68 4.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ming Lei commit f054b56c951bf1731ba7314a4c7f1cc0b2977cc9 upstream. Firstly during CPU hotplug, even queue is freezed, timeout handler still may come and access hctx->tags, which may cause use after free, so this patch deactivates timeout handler inside CPU hotplug notifier. Secondly, tags can be shared by more than one queues, so we have to check if the hctx has been unmapped, otherwise still use-after-free on tags can be triggered. Reported-by: Dongsu Park Tested-by: Dongsu Park Signed-off-by: Ming Lei Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- block/blk-mq.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -675,8 +675,11 @@ static void blk_mq_rq_timer(unsigned lon data.next = blk_rq_timeout(round_jiffies_up(data.next)); mod_timer(&q->timeout, data.next); } else { - queue_for_each_hw_ctx(q, hctx, i) - blk_mq_tag_idle(hctx); + queue_for_each_hw_ctx(q, hctx, i) { + /* the hctx may be unmapped, so check it here */ + if (blk_mq_hw_queue_mapped(hctx)) + blk_mq_tag_idle(hctx); + } } } @@ -2075,9 +2078,16 @@ static int blk_mq_queue_reinit_notify(st */ list_for_each_entry(q, &all_q_list, all_q_node) blk_mq_freeze_queue_start(q); - list_for_each_entry(q, &all_q_list, all_q_node) + list_for_each_entry(q, &all_q_list, all_q_node) { blk_mq_freeze_queue_wait(q); + /* + * timeout handler can't touch hw queue during the + * reinitialization + */ + del_timer_sync(&q->timeout); + } + list_for_each_entry(q, &all_q_list, all_q_node) blk_mq_queue_reinit(q); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/