Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp3148537pxb; Fri, 12 Feb 2021 10:20:14 -0800 (PST) X-Google-Smtp-Source: ABdhPJxup7zJLb3pew108SgchaCXiWAa0ySDBfXI8e2YbsBfPcZe37AetUx5/o5Sv8wseXQQhlZF X-Received: by 2002:a17:906:a153:: with SMTP id bu19mr4401879ejb.287.1613154014693; Fri, 12 Feb 2021 10:20:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1613154014; cv=none; d=google.com; s=arc-20160816; b=Q+drtuuXKI1qmqoeRTgODKqxvQRy9zU5ZRdqqJRcbniqOkqM/dBEcVhew1mhpc8ezb lbYwMtiShxbhWIAkVF9//HxcT3qqk25CrHFEdgCNG7DTAMmkb8ZTeCk6Bl1fDqSJARm+ /rpi1GH1rr3yOR+R/ENNDmbUQo+B8D6YE9r/gB2KjUvMgTKlDM/XcgfNY5wRfRzmHZS8 c8b7AteDtQGupxXNLNSEQ+DPC3wwpTbxFN7+dAAIlhnNGoT5lnKom/ePclGornJx/8pD E6PVJTraroF81bEN7Bi8v7pD2rC6pvb8bVoZoQk+9Ma9pLf4XLbs6L5VKXIt3Pd5nv9m gAlg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=LaMYhgfZE7N5GxueWAHhJKUHrh3KlIIUFH+RE6YysBM=; b=oD+u5k8Gvu6eAGXvCq5/YskksPJ7GlU8UEh/uIuArEAR4QAIfv/B5Dgg5aVyn/bXoH mBnKnQhcXaMbtVvyyqP4FqF/dLIaOl/UUnHARdrHh1ikNOzfzBOrs+LreV4sSpO6l2Yg 5gCzp2ArrJ54QuSOzS0EAlTbF+XKNRsjxPeGpdPLFxhhBNKx7G8LwosFihibTfq41R+l am4LM5dNCeIbbmKTK5OJGwzirD7sus6rnYkwXRKdDvA3F3UUOBAHePOhIPiwYziNdojy jKTylhNz8cpTeEGIW3ye2kMUB6CSC7i4agZRvlRJQEpjpQeZ77sGSJqy2UKbQyPz6w9N Fz5g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c14si6752481edk.65.2021.02.12.10.19.51; Fri, 12 Feb 2021 10:20:14 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231717AbhBLSSc (ORCPT + 99 others); Fri, 12 Feb 2021 13:18:32 -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