From owner-svn-src-head@freebsd.org Mon Apr 30 23:05:58 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B9E05FB8FAA; Mon, 30 Apr 2018 23:05:58 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 5A91E7FB59; Mon, 30 Apr 2018 23:05:58 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4FABE19B89; Mon, 30 Apr 2018 23:05:58 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3UN5wxC090695; Mon, 30 Apr 2018 23:05:58 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3UN5weM090694; Mon, 30 Apr 2018 23:05:58 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201804302305.w3UN5weM090694@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Mon, 30 Apr 2018 23:05:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333130 - head/sys/dev/nvme X-SVN-Group: head X-SVN-Commit-Author: mav X-SVN-Commit-Paths: head/sys/dev/nvme X-SVN-Commit-Revision: 333130 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Apr 2018 23:05:59 -0000 Author: mav Date: Mon Apr 30 23:05:57 2018 New Revision: 333130 URL: https://svnweb.freebsd.org/changeset/base/333130 Log: Improve nvme(4) attach/detach sequences. This change allows clean device detach on attach failures and driver unload, while previous code tried to talk to already shut down controller, or even accessed resources failed to allocate. Sponsored by: iXsystems, Inc. Modified: head/sys/dev/nvme/nvme_ctrlr.c Modified: head/sys/dev/nvme/nvme_ctrlr.c ============================================================================== --- head/sys/dev/nvme/nvme_ctrlr.c Mon Apr 30 21:56:08 2018 (r333129) +++ head/sys/dev/nvme/nvme_ctrlr.c Mon Apr 30 23:05:57 2018 (r333130) @@ -1203,6 +1203,7 @@ nvme_ctrlr_setup_interrupts(struct nvme_controller *ct int nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev) { + struct make_dev_args md_args; uint32_t cap_lo; uint32_t cap_hi; uint8_t to; @@ -1254,14 +1255,6 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, de if (nvme_ctrlr_construct_admin_qpair(ctrlr) != 0) return (ENXIO); - ctrlr->cdev = make_dev(&nvme_ctrlr_cdevsw, device_get_unit(dev), - UID_ROOT, GID_WHEEL, 0600, "nvme%d", device_get_unit(dev)); - - if (ctrlr->cdev == NULL) - return (ENXIO); - - ctrlr->cdev->si_drv1 = (void *)ctrlr; - ctrlr->taskqueue = taskqueue_create("nvme_taskq", M_WAITOK, taskqueue_thread_enqueue, &ctrlr->taskqueue); taskqueue_start_threads(&ctrlr->taskqueue, 1, PI_DISK, "nvme taskq"); @@ -1270,11 +1263,22 @@ nvme_ctrlr_construct(struct nvme_controller *ctrlr, de ctrlr->is_initialized = 0; ctrlr->notification_sent = 0; TASK_INIT(&ctrlr->reset_task, 0, nvme_ctrlr_reset_task, ctrlr); - TASK_INIT(&ctrlr->fail_req_task, 0, nvme_ctrlr_fail_req_task, ctrlr); STAILQ_INIT(&ctrlr->fail_req); ctrlr->is_failed = FALSE; + make_dev_args_init(&md_args); + md_args.mda_devsw = &nvme_ctrlr_cdevsw; + md_args.mda_uid = UID_ROOT; + md_args.mda_gid = GID_WHEEL; + md_args.mda_mode = 0600; + md_args.mda_unit = device_get_unit(dev); + md_args.mda_si_drv1 = (void *)ctrlr; + status = make_dev_s(&md_args, &ctrlr->cdev, "nvme%d", + device_get_unit(dev)); + if (status != 0) + return (ENXIO); + return (0); } @@ -1283,18 +1287,9 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, dev { int i; - /* - * Notify the controller of a shutdown, even though this is due to - * a driver unload, not a system shutdown (this path is not invoked - * during shutdown). This ensures the controller receives a - * shutdown notification in case the system is shutdown before - * reloading the driver. - */ - nvme_ctrlr_shutdown(ctrlr); + if (ctrlr->resource == NULL) + goto nores; - nvme_ctrlr_disable(ctrlr); - taskqueue_free(ctrlr->taskqueue); - for (i = 0; i < NVME_MAX_NAMESPACES; i++) nvme_ns_destruct(&ctrlr->ns[i]); @@ -1305,21 +1300,24 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, dev nvme_ctrlr_destroy_qpair(ctrlr, &ctrlr->ioq[i]); nvme_io_qpair_destroy(&ctrlr->ioq[i]); } - free(ctrlr->ioq, M_NVME); nvme_admin_qpair_destroy(&ctrlr->adminq); - if (ctrlr->resource != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - ctrlr->resource_id, ctrlr->resource); - } + /* + * Notify the controller of a shutdown, even though this is due to + * a driver unload, not a system shutdown (this path is not invoked + * during shutdown). This ensures the controller receives a + * shutdown notification in case the system is shutdown before + * reloading the driver. + */ + nvme_ctrlr_shutdown(ctrlr); - if (ctrlr->bar4_resource != NULL) { - bus_release_resource(dev, SYS_RES_MEMORY, - ctrlr->bar4_resource_id, ctrlr->bar4_resource); - } + nvme_ctrlr_disable(ctrlr); + if (ctrlr->taskqueue) + taskqueue_free(ctrlr->taskqueue); + if (ctrlr->tag) bus_teardown_intr(ctrlr->dev, ctrlr->res, ctrlr->tag); @@ -1329,6 +1327,17 @@ nvme_ctrlr_destruct(struct nvme_controller *ctrlr, dev if (ctrlr->msix_enabled) pci_release_msi(dev); + + if (ctrlr->bar4_resource != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, + ctrlr->bar4_resource_id, ctrlr->bar4_resource); + } + + bus_release_resource(dev, SYS_RES_MEMORY, + ctrlr->resource_id, ctrlr->resource); + +nores: + mtx_destroy(&ctrlr->lock); } void