From nobody Tue Oct 10 22:26:20 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4S4r8r2Wt2z4wQgG; Tue, 10 Oct 2023 22:26:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4S4r8r23sQz4H5Z; Tue, 10 Oct 2023 22:26:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1696976780; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=jEugMixrdfDFwCrBQUa15VWT8SFBa+fMdzCh8eCuRYU=; b=NrmCQXE9KChNru/n7kQoJtBVIaLAIoeh7JK4h0C4GrbhZbir3rICBX6p99NxmpLlmy6kl6 q4dOpooP7qHUo211AvbVmvA5PthIQ5ISfGcF5wKW6NcRIML07+e80+F+fefDzA7m+lfSb3 vdTDMVpyMpN891jbMaxeV2xJX3pLgyYt7BX0akgZEBwYuu+ZFHIAiYCJndwPQpoKLmvZvw 1+0x5bznfq5yHflt8mWs9D/PUGM8DptKDdwEF9Ol0u2FTS4IL2ErL+4orYC0GnPAK4xRZ4 VLK5ykgAr48RqbVoFner/sq7Tku8nVUm8Kl0ItVWMU/HYn840bVYe602F3jWOw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1696976780; a=rsa-sha256; cv=none; b=SDHSEOH0LoeOL5kGDBBG7GfzpSyA/3yIrfL5SUkoi3MWJSuNSvTZfsHRs/hIHQu+7xRYPA yEjDHS6ec4WgQuvjrcQKh/MR4nQLyS2rXsd2ZUuglmc+Bz6NnBk7kmnbDpRpeaVeZo6zZO K+Ewt9yymLkI/zYkGWRmNWxwlFCa2QEDbNBxwoc5ePo9Umwp0dxqCcsDHk4nOlirNlA4KR aek/ytjghvozqAMM5AjYkV4aOyBFcn5oLTOHw5DzFv51okQoI/KPmP5lN/htvNDrmOUyoS v474L6eHDw0BFetwp7xZTTAWEYEoHUFNbkRu6NEp2DeNsJ7RzhDWYUUiij7eWA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1696976780; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=jEugMixrdfDFwCrBQUa15VWT8SFBa+fMdzCh8eCuRYU=; b=OWeN4nIneUTT6wpsDZRnAmLWnGIhmldLXHtiUXy/SPWKWgNCtVfqc0StTnL8jOrqyOgLyi ccvtB46/lx/RXelYSxns+9N5ybtxez5M1veMV99ntiocljS/SkmTNI8Je4c6L4YlWRY9RB cK3bewoyVPalfg22TcHDo1fCrqpZvTV9ZEeBqZhTXvpKG8Gqs//hmChOPmGfVabufYePRb wMVru8c77Ug1zs+WMYCuEjlBwK6oXJ5CVqvF5qLkiuh0CHgKwdwcAZ9/L3DdPazHbaMEgi uZC2FfAnMTJf4HJeTOYqFbggF21mDrOXfNd7Cg0oi0fJAvscs076GLGr3rUHkQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4S4r8r191bzwTy; Tue, 10 Oct 2023 22:26:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 39AMQKeY085552; Tue, 10 Oct 2023 22:26:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39AMQKYn085549; Tue, 10 Oct 2023 22:26:20 GMT (envelope-from git) Date: Tue, 10 Oct 2023 22:26:20 GMT Message-Id: <202310102226.39AMQKYn085549@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: afc3d49b17a3 - main - nvme: Close a race in destroying qpair and timeouts List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: afc3d49b17a35db3b70c9e4f63a508a14a8237fe Auto-Submitted: auto-generated The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=afc3d49b17a35db3b70c9e4f63a508a14a8237fe commit afc3d49b17a35db3b70c9e4f63a508a14a8237fe Author: Warner Losh AuthorDate: 2023-10-10 17:13:25 +0000 Commit: Warner Losh CommitDate: 2023-10-10 22:13:57 +0000 nvme: Close a race in destroying qpair and timeouts While we should have cleared all the pending I/O prior to calling nvme_qpair_destroy, which should ensure that if the callout_drain causes a call to nvme_qpair_timeout(), it won't schedule any new timeout. However, it doesn't hurt to set timeout_pending to false in nvme_qpair_destroy() and have nvme_qpair_timeout() exit early if it sees it w/o scheduling a timeout. Since we don't otherwise stop the timeout until we're about to destroy the qpair, this ensures we fail safe. The lock/unlock also ensures the callout_drain will either remove the callout, or wait for it to run with the early bailout. We can likely further improve this by using callout_stop() inside the pending lock. I'll investigate that for future refinement. Sponsored by: Netflix Suggestions by: jhb Reviewed by: gallatin Differential Revision: https://reviews.freebsd.org/D42065 --- sys/dev/nvme/nvme_qpair.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index 6d9d337e76a5..569d54ab6aef 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -727,6 +727,10 @@ nvme_qpair_construct(struct nvme_qpair *qpair, mtx_init(&qpair->lock, "nvme qpair lock", NULL, MTX_DEF); mtx_init(&qpair->recovery, "nvme qpair recovery", NULL, MTX_DEF); + callout_init_mtx(&qpair->timer, &qpair->recovery, 0); + qpair->timer_armed = false; + qpair->recovery_state = RECOVERY_WAITING; + /* Note: NVMe PRP format is restricted to 4-byte alignment. */ err = bus_dma_tag_create(bus_get_dma_tag(ctrlr->dev), 4, ctrlr->page_size, BUS_SPACE_MAXADDR, @@ -792,10 +796,6 @@ nvme_qpair_construct(struct nvme_qpair *qpair, qpair->cpl_bus_addr = queuemem_phys + cmdsz; prpmem_phys = queuemem_phys + cmdsz + cplsz; - callout_init_mtx(&qpair->timer, &qpair->recovery, 0); - qpair->timer_armed = false; - qpair->recovery_state = RECOVERY_WAITING; - /* * Calcuate the stride of the doorbell register. Many emulators set this * value to correspond to a cache line. However, some hardware has set @@ -891,6 +891,9 @@ nvme_qpair_destroy(struct nvme_qpair *qpair) { struct nvme_tracker *tr; + mtx_lock(&qpair->recovery); + qpair->timer_armed = false; + mtx_unlock(&qpair->recovery); callout_drain(&qpair->timer); if (qpair->tag) { @@ -1039,6 +1042,19 @@ nvme_qpair_timeout(void *arg) return; } + /* + * Shutdown condition: We set qpair->timer_armed to false in + * nvme_qpair_destroy before calling callout_drain. When we call that, + * this routine might get called one last time. Exit w/o setting a + * timeout. None of the watchdog stuff needs to be done since we're + * destroying the qpair. + */ + if (!qpair->timer_armed) { + nvme_printf(qpair->ctrlr, + "Timeout fired during nvme_qpair_destroy\n"); + return; + } + switch (qpair->recovery_state) { case RECOVERY_NONE: /*