Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp434387imu; Wed, 12 Dec 2018 20:48:29 -0800 (PST) X-Google-Smtp-Source: AFSGD/Vmn1lfezBmsYwfK5e4dPAfZMpzBHYQdgtNHVUIzSzld9aW8x/8Gyp8VYlMb5oYs3X9+Drt X-Received: by 2002:a63:31cc:: with SMTP id x195mr1174445pgx.52.1544676509247; Wed, 12 Dec 2018 20:48:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544676509; cv=none; d=google.com; s=arc-20160816; b=sM2lp0t855eHnAUS/I7RM1MQJ3vKLi5DU7SWwdlxJyOQyPl1SRYOuM69zHVMiRZ8Go eijQemnrs4PE0XkPGmDKdLA1Jsz/y8NgCUJBT4yUda3dHuwLTvtHnnHDg1ZqZIhE3gqJ D7oOQ1jGO0jOGf5G7i8upO/Y9OQOTs1Ct+LWAmHzPLK85NFYy65UP41Ru1jmIruSbZH9 IhM6Cz9642eyb7y5B2tRc03ktiXIcObE5HZXtWSkkXrSe3+OID5TGvvzP+0TTU2h6j33 mXxbqOg3W6UL1Q8Wei1ooa+6ghpjQ+2nx+jtnByk1YwmMkpKAHw/obasuK1sgvLhmp10 O6Pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ry+qt4/2zGTCz/DDttAIS2qG4XJ3FEcpudoe72+R+Ws=; b=r2CmeocKY2krLcXDC10oWKy8h4S4hrGblB/ciXwDUYH0ie3OSiSD0m5qlHChoFrgvx bLX6zg+39+CgtIrIaebx/wz05zlV7QPThzH1NA92O3v361cbY+11nLIwqaYiPIYw4aRz +OzmjIrr5iKCrFqQyKE7PhjRzlmBrBm1Y6NC9Qhp2f4oC9hHxMOhFO8Wof1samMHKAg1 nhUEV20af7apoX+8j0Y81Bf6dc9Y1LuvEpSIwbNrHqRKRn0Bf1g6KY6BsXmqEd6wD9ck LArwgx0Ree5ftGo6sEIXliJ4Ie32i9odlDx7mumUjF+21zEgw1CPDrP+GIpUetspfuql f6ug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IawTy8P1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j34si634258pgj.557.2018.12.12.20.48.14; Wed, 12 Dec 2018 20:48:29 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=IawTy8P1; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728830AbeLMEqB (ORCPT + 99 others); Wed, 12 Dec 2018 23:46:01 -0500 Received: from mail.kernel.org ([198.145.29.99]:43672 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727406AbeLMEat (ORCPT ); Wed, 12 Dec 2018 23:30:49 -0500 Received: from sasha-vm.mshome.net (c-73-47-72-35.hsd1.nh.comcast.net [73.47.72.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 2ED0820989; Thu, 13 Dec 2018 04:30:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1544675448; bh=66bIVOUhszalWq34bmkerV14UFkvSHRPxHOyFzoG0Rw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IawTy8P1U1l3pVoDP6OOqVGQSKDds8Ps9RLc85Ung+5YvCv30LKTSbQJRQB0wYrZa 7IGSo6Va3yzTn5swkiN6U+DR0czBYmTI9x/U8Buzs+cB1U02/+7atln9LbAkO86jYy XZT/ynDdvm+igAGORxlNfC4rxugLowXFqeAy+7lo= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: James Smart , Christoph Hellwig , Sasha Levin , linux-nvme@lists.infradead.org Subject: [PATCH AUTOSEL 4.19 70/73] nvme: validate controller state before rescheduling keep alive Date: Wed, 12 Dec 2018 23:28:35 -0500 Message-Id: <20181213042838.75160-70-sashal@kernel.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181213042838.75160-1-sashal@kernel.org> References: <20181213042838.75160-1-sashal@kernel.org> MIME-Version: 1.0 X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: James Smart [ Upstream commit 86880d646122240596d6719b642fee3213239994 ] Delete operations are seeing NULL pointer references in call_timer_fn. Tracking these back, the timer appears to be the keep alive timer. nvme_keep_alive_work() which is tied to the timer that is cancelled by nvme_stop_keep_alive(), simply starts the keep alive io but doesn't wait for it's completion. So nvme_stop_keep_alive() only stops a timer when it's pending. When a keep alive is in flight, there is no timer running and the nvme_stop_keep_alive() will have no affect on the keep alive io. Thus, if the io completes successfully, the keep alive timer will be rescheduled. In the failure case, delete is called, the controller state is changed, the nvme_stop_keep_alive() is called while the io is outstanding, and the delete path continues on. The keep alive happens to successfully complete before the delete paths mark it as aborted as part of the queue termination, so the timer is restarted. The delete paths then tear down the controller, and later on the timer code fires and the timer entry is now corrupt. Fix by validating the controller state before rescheduling the keep alive. Testing with the fix has confirmed the condition above was hit. Signed-off-by: James Smart Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/core.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 0ba301f7e8b4..05bd7f49d6e0 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -831,6 +831,8 @@ static int nvme_submit_user_cmd(struct request_queue *q, static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) { struct nvme_ctrl *ctrl = rq->end_io_data; + unsigned long flags; + bool startka = false; blk_mq_free_request(rq); @@ -841,7 +843,13 @@ static void nvme_keep_alive_end_io(struct request *rq, blk_status_t status) return; } - schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); + spin_lock_irqsave(&ctrl->lock, flags); + if (ctrl->state == NVME_CTRL_LIVE || + ctrl->state == NVME_CTRL_CONNECTING) + startka = true; + spin_unlock_irqrestore(&ctrl->lock, flags); + if (startka) + schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); } static int nvme_keep_alive(struct nvme_ctrl *ctrl) -- 2.19.1