From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1035C433DB for ; Fri, 12 Feb 2021 18:18:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 96ECD64E8E for ; Fri, 12 Feb 2021 18:18:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231816AbhBLSSd (ORCPT ); Fri, 12 Feb 2021 13:18:33 -0500 Received: from mx2.suse.de ([195.135.220.15]:58538 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231348AbhBLSSa (ORCPT ); Fri, 12 Feb 2021 13:18:30 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 6759AAFEC; Fri, 12 Feb 2021 18:17:46 +0000 (UTC) From: Daniel Wagner To: linux-nvme@lists.infradead.org Cc: linux-kernel@vger.kernel.org, Sagi Grimberg , Christoph Hellwig , Jens Axboe , Keith Busch , Hannes Reinecke , Daniel Wagner Subject: [PATCH] nvme-tcp: Check if request has started before processing it Date: Fri, 12 Feb 2021 19:17:38 +0100 Message-Id: <20210212181738.79274-1-dwagner@suse.de> X-Mailer: git-send-email 2.29.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org blk_mq_tag_to_rq() will always return a request if the command_id is in the valid range. Check if the request has been started. If we blindly process the request we might double complete a request which can be fatal. Signed-off-by: Daniel Wagner --- This patch is against nvme-5.12. There is one blk_mq_tag_to_rq() in nvme_tcp_recv_ddgst() which I didn't update as I am not sure if it's also needed. py-crash> bt #0 0xffffffffa76a33de in arch_atomic_try_cmpxchg (new=, old=, v=) at ../arch/x86/include/asm/atomic.h:200 #1 atomic_try_cmpxchg (new=, old=, v=) at ../include/asm-generic/atomic-instrumented.h:695 #2 queued_spin_lock (lock=) at ../include/asm-generic/qspinlock.h:78 #3 do_raw_spin_lock_flags (flags=, lock=) at ../include/linux/spinlock.h:193 #4 __raw_spin_lock_irqsave (lock=) at ../include/linux/spinlock_api_smp.h:119 #5 _raw_spin_lock_irqsave (lock=0x8 <__UNIQUE_ID_license257+8>) at ../kernel/locking/spinlock.c:159 #6 0xffffffffa6eea418 in complete (x=0x0 <__UNIQUE_ID_license257>) at ../kernel/sched/completion.c:32 #7 0xffffffffa721f99c in blk_mq_force_complete_rq (rq=0x8 <__UNIQUE_ID_license257+8>) at ../block/blk-mq.c:634 #8 0xffffffffa721fa0a in blk_mq_complete_request (rq=) at ../block/blk-mq.c:672 #9 0xffffffffc0b092ef in nvme_end_request (result=..., status=, req=) at ../drivers/nvme/host/nvme.h:477 #10 nvme_tcp_process_nvme_cqe (cqe=, queue=) at ../drivers/nvme/host/tcp.c:485 rq = 0xffff948b840d0000 hdr = ret = 0 queue = 0xffff949501dd8110 result = 0 #11 nvme_tcp_handle_comp (pdu=, queue=) at ../drivers/nvme/host/tcp.c:542 #12 nvme_tcp_recv_pdu (len=, offset=, skb=, queue=) at ../drivers/nvme/host/tcp.c:660 #13 nvme_tcp_recv_skb (desc=, skb=, offset=24, len=0) at ../drivers/nvme/host/tcp.c:805 #14 0xffffffffa7598af5 in tcp_read_sock (sk=0x8 <__UNIQUE_ID_license257+8>, desc=0xa <__UNIQUE_ID_license257+10>, recv_actor=0x1 <__UNIQUE_ID_license257+1>) at ../net/ipv4/tcp.c:1645 #15 0xffffffffc0b075b8 in nvme_tcp_try_recv (queue=0xffff949501dd8110) at ../drivers/nvme/host/tcp.c:1102 #16 0xffffffffc0b08fc7 in nvme_tcp_io_work (w=0xffff949501dd8118) at ../drivers/nvme/host/tcp.c:1126 #17 0xffffffffa6eba4e4 in process_one_work (worker=0xffff948d1b633ec0, work=0xffff949501dd8118) at ../kernel/workqueue.c:2273 #18 0xffffffffa6eba6fd in worker_thread (__worker=0xffff948d1b633ec0) at ../kernel/workqueue.c:2419 #19 0xffffffffa6ec0a3d in kthread (_create=0xffff948d1b618ec0) at ../kernel/kthread.c:268 #20 0xffffffffa7800215 in ret_from_fork () at ../arch/x86/entry/entry_64.S:351 py-crash> p /x ((struct request*)0xffff948b840d0000)->state $2 = 0x2 drivers/nvme/host/tcp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 69f59d2c5799..4bec705ce8e6 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -485,7 +485,7 @@ static int nvme_tcp_process_nvme_cqe(struct nvme_tcp_queue *queue, struct request *rq; rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), cqe->command_id); - if (!rq) { + if (!rq || !blk_mq_request_started(rq)) { dev_err(queue->ctrl->ctrl.device, "queue %d tag 0x%x not found\n", nvme_tcp_queue_id(queue), cqe->command_id); @@ -506,7 +506,7 @@ static int nvme_tcp_handle_c2h_data(struct nvme_tcp_queue *queue, struct request *rq; rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); - if (!rq) { + if (!rq || !blk_mq_request_started(rq)) { dev_err(queue->ctrl->ctrl.device, "queue %d tag %#x not found\n", nvme_tcp_queue_id(queue), pdu->command_id); @@ -610,7 +610,7 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue, int ret; rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); - if (!rq) { + if (!rq || !blk_mq_request_started(rq)) { dev_err(queue->ctrl->ctrl.device, "queue %d tag %#x not found\n", nvme_tcp_queue_id(queue), pdu->command_id); @@ -696,7 +696,7 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, struct request *rq; rq = blk_mq_tag_to_rq(nvme_tcp_tagset(queue), pdu->command_id); - if (!rq) { + if (!rq || !blk_mq_request_started(rq)) { dev_err(queue->ctrl->ctrl.device, "queue %d tag %#x not found\n", nvme_tcp_queue_id(queue), pdu->command_id); -- 2.29.2