From owner-svn-src-head@freebsd.org Wed May 2 20:13:04 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 EE76BFB32AA; Wed, 2 May 2018 20:13:03 +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 99A6B7636E; Wed, 2 May 2018 20:13:03 +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 91A5A15B40; Wed, 2 May 2018 20:13:03 +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 w42KD3YO058819; Wed, 2 May 2018 20:13:03 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w42KD3s2058818; Wed, 2 May 2018 20:13:03 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201805022013.w42KD3s2058818@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Wed, 2 May 2018 20:13:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333180 - 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: 333180 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: Wed, 02 May 2018 20:13:04 -0000 Author: mav Date: Wed May 2 20:13:03 2018 New Revision: 333180 URL: https://svnweb.freebsd.org/changeset/base/333180 Log: Fix LOR between controller and queue locks. Admin pass-through requests took controller lock before the queue lock, but in case of request submission to a failed controller controller lock was taken after the queue lock. Fix that by reducing the lock scopes and switching to mtx_pool locks to track pass-through request completion. 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 Wed May 2 20:10:27 2018 (r333179) +++ head/sys/dev/nvme/nvme_ctrlr.c Wed May 2 20:13:03 2018 (r333180) @@ -233,11 +233,12 @@ nvme_ctrlr_fail_req_task(void *arg, int pending) struct nvme_request *req; mtx_lock(&ctrlr->lock); - while (!STAILQ_EMPTY(&ctrlr->fail_req)) { - req = STAILQ_FIRST(&ctrlr->fail_req); + while ((req = STAILQ_FIRST(&ctrlr->fail_req)) != NULL) { STAILQ_REMOVE_HEAD(&ctrlr->fail_req, stailq); + mtx_unlock(&ctrlr->lock); nvme_qpair_manual_complete_request(req->qpair, req, NVME_SCT_GENERIC, NVME_SC_ABORTED_BY_REQUEST, TRUE); + mtx_lock(&ctrlr->lock); } mtx_unlock(&ctrlr->lock); } @@ -978,6 +979,7 @@ static void nvme_pt_done(void *arg, const struct nvme_completion *cpl) { struct nvme_pt_command *pt = arg; + struct mtx *mtx = pt->driver_lock; uint16_t status; bzero(&pt->cpl, sizeof(pt->cpl)); @@ -987,9 +989,10 @@ nvme_pt_done(void *arg, const struct nvme_completion * status &= ~NVME_STATUS_P_MASK; pt->cpl.status = status; - mtx_lock(pt->driver_lock); + mtx_lock(mtx); + pt->driver_lock = NULL; wakeup(pt); - mtx_unlock(pt->driver_lock); + mtx_unlock(mtx); } int @@ -1058,15 +1061,7 @@ nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctr req->cmd.nsid = htole32(nsid); - if (is_admin_cmd) - mtx = &ctrlr->lock; - else { - KASSERT((nsid-1) >= 0 && (nsid-1) < NVME_MAX_NAMESPACES, - ("%s: invalid namespace ID %d\n", __func__, nsid)); - mtx = &ctrlr->ns[nsid-1].lock; - } - - mtx_lock(mtx); + mtx = mtx_pool_find(mtxpool_sleep, pt); pt->driver_lock = mtx; if (is_admin_cmd) @@ -1074,10 +1069,10 @@ nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctr else nvme_ctrlr_submit_io_request(ctrlr, req); - mtx_sleep(pt, mtx, PRIBIO, "nvme_pt", 0); + mtx_lock(mtx); + while (pt->driver_lock != NULL) + mtx_sleep(pt, mtx, PRIBIO, "nvme_pt", 0); mtx_unlock(mtx); - - pt->driver_lock = NULL; err: if (buf != NULL) {