From owner-dev-commits-src-main@freebsd.org Thu Jul 15 22:18:17 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 6881765205D; Thu, 15 Jul 2021 22:18:17 +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 4GQpfd2RYBz4gR7; Thu, 15 Jul 2021 22:18:17 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 3C8AF11CCA; Thu, 15 Jul 2021 22:18:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16FMIH84020868; Thu, 15 Jul 2021 22:18:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16FMIHsl020867; Thu, 15 Jul 2021 22:18:17 GMT (envelope-from git) Date: Thu, 15 Jul 2021 22:18:17 GMT Message-Id: <202107152218.16FMIHsl020867@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: fc9a08402317 - main - nvme: Enable interrupts after qpair fully constructed 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: fc9a0840231770bc7e7dcfe4616babdc6d4389a6 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Jul 2021 22:18:17 -0000 The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=fc9a0840231770bc7e7dcfe4616babdc6d4389a6 commit fc9a0840231770bc7e7dcfe4616babdc6d4389a6 Author: Warner Losh AuthorDate: 2021-07-15 22:17:23 +0000 Commit: Warner Losh CommitDate: 2021-07-15 22:17:23 +0000 nvme: Enable interrupts after qpair fully constructed To guard against the ill effects of a spurious interrupt during construction (or one that was bogusly pending), enable interrupts after the qpair is completely constructed. Otherwise, we can die with null pointer dereferences in nvme_qpair_process_completions. This has been observed in at least one pre-release NVMe drive where the MSIX interrupt fired while the queue was being created, before we'd started the NVMe controller card. The alternative of only turning on the interrupts after the rest was tried, but was insufficient to work around this bug and made the code more complicated w/o benefit. Reviewed by: mav, chuck Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D31182 --- sys/dev/nvme/nvme_qpair.c | 49 ++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index 12770f38d42e..4402d1000e67 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -675,30 +675,6 @@ nvme_qpair_construct(struct nvme_qpair *qpair, qpair->num_trackers = num_trackers; qpair->ctrlr = ctrlr; - if (ctrlr->msix_enabled) { - /* - * MSI-X vector resource IDs start at 1, so we add one to - * the queue's vector to get the corresponding rid to use. - */ - qpair->rid = qpair->vector + 1; - - qpair->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ, - &qpair->rid, RF_ACTIVE); - if (bus_setup_intr(ctrlr->dev, qpair->res, - INTR_TYPE_MISC | INTR_MPSAFE, NULL, - nvme_qpair_msix_handler, qpair, &qpair->tag) != 0) { - nvme_printf(ctrlr, "unable to setup intx handler\n"); - goto out; - } - if (qpair->id == 0) { - bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag, - "admin"); - } else { - bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag, - "io%d", qpair->id - 1); - } - } - mtx_init(&qpair->lock, "nvme qpair lock", NULL, MTX_DEF); /* Note: NVMe PRP format is restricted to 4-byte alignment. */ @@ -818,6 +794,31 @@ nvme_qpair_construct(struct nvme_qpair *qpair, qpair->act_tr = malloc_domainset(sizeof(struct nvme_tracker *) * qpair->num_entries, M_NVME, DOMAINSET_PREF(qpair->domain), M_ZERO | M_WAITOK); + + if (ctrlr->msix_enabled) { + /* + * MSI-X vector resource IDs start at 1, so we add one to + * the queue's vector to get the corresponding rid to use. + */ + qpair->rid = qpair->vector + 1; + + qpair->res = bus_alloc_resource_any(ctrlr->dev, SYS_RES_IRQ, + &qpair->rid, RF_ACTIVE); + if (bus_setup_intr(ctrlr->dev, qpair->res, + INTR_TYPE_MISC | INTR_MPSAFE, NULL, + nvme_qpair_msix_handler, qpair, &qpair->tag) != 0) { + nvme_printf(ctrlr, "unable to setup intx handler\n"); + goto out; + } + if (qpair->id == 0) { + bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag, + "admin"); + } else { + bus_describe_intr(ctrlr->dev, qpair->res, qpair->tag, + "io%d", qpair->id - 1); + } + } + return (0); out: