From nobody Thu Feb 20 15:40:41 2025 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 4YzHXT6B0qz5p3Vt; Thu, 20 Feb 2025 15:40:41 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YzHXT5X8rz4Hsp; Thu, 20 Feb 2025 15:40:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1740066041; 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=l5KlP35HVe+goHM7Ih3UfQyaRVtysL6aSpr4cheLkvI=; b=Po3xLe2JhEDAWtwJelBigoL5raI+E5QUyhwJvnJcRSemAaIcz//EFZSICP0j6BD+gB4SgZ Od8Y6N7OPZGBMQapaz8QQOnevHpOdJ5+7E8bce7DDWYRjhT352YAd0w6tR29TuVsllPveW we4im9ep6omWnD4cbSEKKXuSqdVKsWlp5E5FJzBE/LomySGtJUt7eF8WKYKTINA0Ys7R3o QOALYxd08AB7U1PBvHn9soKnFAlHVuDVTBsdc9SItb+k3lRRs5sYVXXucDmohZJ5Zf7cAM +/kKtdanZcWUBQaJcZaCeFS/pniffeyka0V9fRbxPQ/w/qUrNIavhjhAvgef8A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1740066041; a=rsa-sha256; cv=none; b=vgICCVQbs9KwR9BR3JynhAfEGCI1CeE1v+O2PBoT1LX8ao5E4Hfpxchum4IZVucWXd7qqj bh3Mzu7ESUJ43Q8ZtPTbPDEgENQs4FnOHWGZxsQoB8CypubhenRRPMpBqdZhAubb1e9Lvf e8k8tlPOre2/Lp0xVvOh1YROCxcfGe+zNgooyl2kgXMQCEsE2Y26D5ZrF0yLXhhGod7zd8 C7lIpzaVErjzpMf2MmbuR/QsS25bDnhMEczvtzjJRPDtHvog7Pe9v+SGA3GaMp2Ode8m5Y TmJ3ldFSlL98dIE1lawyf6ZhYEA+enubyCShgHUGMtuNZVjjVV4eZCpFgHPC1A== 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=1740066041; 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=l5KlP35HVe+goHM7Ih3UfQyaRVtysL6aSpr4cheLkvI=; b=yy4GEyXxBXrbI5QgVltlRPJdjJ5AymUTnb6BeTY0v1t1en16V9L2ubUAS1nqzWjvuOH+Iy EguHJHO3gZtzDnrjyDZsVuUxXsua2lo8w8b28slpWXiB+NhNN8RzFashokcfENE5+X9jvt j7N6M5zbGwY/nWxFySaeKbubw9fHai8RmVRCCoMijRLP4727ZIj2O31Jmp+ytdDWbCQUQj FiCiPDrFbgabnOwuEmJHjwjnMkCf7dgCD8tUPzQ5OL8mejAnIQbbgtMvdvh7ZvA9upyjea fjQBDnukH2wAjtTqrBvzAOkCmXgjH1fcW2/rESQpZcCPzq5LXWciPxSO0TFIBA== 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 4YzHXT4pNpzyBB; Thu, 20 Feb 2025 15:40:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51KFefnc016896; Thu, 20 Feb 2025 15:40:41 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51KFef5Y016893; Thu, 20 Feb 2025 15:40:41 GMT (envelope-from git) Date: Thu, 20 Feb 2025 15:40:41 GMT Message-Id: <202502201540.51KFef5Y016893@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: 97ca2ada80b8 - main - nvmft: Switch the per-port lock from sx(9) to mtx(9) 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: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 97ca2ada80b870edbbb4f66b26e274cf8e55e0bc Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=97ca2ada80b870edbbb4f66b26e274cf8e55e0bc commit 97ca2ada80b870edbbb4f66b26e274cf8e55e0bc Author: John Baldwin AuthorDate: 2025-02-20 15:14:16 +0000 Commit: John Baldwin CommitDate: 2025-02-20 15:31:20 +0000 nvmft: Switch the per-port lock from sx(9) to mtx(9) This is needed to avoid LORs for a following commit. Sponsored by: Chelsio Communications --- sys/dev/nvmf/controller/ctl_frontend_nvmf.c | 58 ++++++++++++++++------------- sys/dev/nvmf/controller/nvmft_controller.c | 46 ++++++++++++++--------- sys/dev/nvmf/controller/nvmft_var.h | 2 +- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/sys/dev/nvmf/controller/ctl_frontend_nvmf.c b/sys/dev/nvmf/controller/ctl_frontend_nvmf.c index fcfa8b90ebb7..a28a613e23aa 100644 --- a/sys/dev/nvmf/controller/ctl_frontend_nvmf.c +++ b/sys/dev/nvmf/controller/ctl_frontend_nvmf.c @@ -70,9 +70,9 @@ nvmft_online(void *arg) { struct nvmft_port *np = arg; - sx_xlock(&np->lock); + mtx_lock(&np->lock); np->online = true; - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); } static void @@ -81,7 +81,7 @@ nvmft_offline(void *arg) struct nvmft_port *np = arg; struct nvmft_controller *ctrlr; - sx_xlock(&np->lock); + mtx_lock(&np->lock); np->online = false; TAILQ_FOREACH(ctrlr, &np->controllers, link) { @@ -91,8 +91,8 @@ nvmft_offline(void *arg) } while (!TAILQ_EMPTY(&np->controllers)) - sx_sleep(np, &np->lock, 0, "nvmfoff", 0); - sx_xunlock(&np->lock); + mtx_sleep(np, &np->lock, 0, "nvmfoff", 0); + mtx_unlock(&np->lock); } static int @@ -102,7 +102,7 @@ nvmft_lun_enable(void *arg, int lun_id) struct nvmft_controller *ctrlr; uint32_t *old_ns, *new_ns; uint32_t nsid; - u_int i; + u_int i, new_count; if (lun_id >= le32toh(np->cdata.nn)) { printf("NVMFT: %s lun %d larger than maximum nsid %u\n", @@ -111,14 +111,22 @@ nvmft_lun_enable(void *arg, int lun_id) } nsid = lun_id + 1; - sx_xlock(&np->lock); - new_ns = mallocarray(np->num_ns + 1, sizeof(*new_ns), M_NVMFT, - M_WAITOK); + mtx_lock(&np->lock); + for (;;) { + new_count = np->num_ns + 1; + mtx_unlock(&np->lock); + new_ns = mallocarray(new_count, sizeof(*new_ns), M_NVMFT, + M_WAITOK); + mtx_lock(&np->lock); + if (np->num_ns + 1 <= new_count) + break; + free(new_ns, M_NVMFT); + } for (i = 0; i < np->num_ns; i++) { if (np->active_ns[i] < nsid) continue; if (np->active_ns[i] == nsid) { - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); free(new_ns, M_NVMFT); printf("NVMFT: %s duplicate lun %d\n", np->cdata.subnqn, lun_id); @@ -145,7 +153,7 @@ nvmft_lun_enable(void *arg, int lun_id) nvmft_controller_lun_changed(ctrlr, lun_id); } - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); free(old_ns, M_NVMFT); return (0); @@ -163,12 +171,12 @@ nvmft_lun_disable(void *arg, int lun_id) return (0); nsid = lun_id + 1; - sx_xlock(&np->lock); + mtx_lock(&np->lock); for (i = 0; i < np->num_ns; i++) { if (np->active_ns[i] == nsid) goto found; } - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); printf("NVMFT: %s request to disable nonexistent lun %d\n", np->cdata.subnqn, lun_id); return (EINVAL); @@ -185,7 +193,7 @@ found: nvmft_controller_lun_changed(ctrlr, lun_id); } - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); return (0); } @@ -196,7 +204,7 @@ nvmft_populate_active_nslist(struct nvmft_port *np, uint32_t nsid, { u_int i, count; - sx_slock(&np->lock); + mtx_lock(&np->lock); count = 0; for (i = 0; i < np->num_ns; i++) { if (np->active_ns[i] <= nsid) @@ -206,7 +214,7 @@ nvmft_populate_active_nslist(struct nvmft_port *np, uint32_t nsid, if (count == nitems(nslist->ns)) break; } - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); } void @@ -625,7 +633,7 @@ nvmft_port_free(struct nvmft_port *np) free(np->active_ns, M_NVMFT); clean_unrhdr(np->ids); delete_unrhdr(np->ids); - sx_destroy(&np->lock); + mtx_destroy(&np->lock); free(np, M_NVMFT); } @@ -797,7 +805,7 @@ nvmft_port_create(struct ctl_req *req) refcount_init(&np->refs, 1); np->max_io_qsize = max_io_qsize; np->cap = _nvmf_controller_cap(max_io_qsize, enable_timeout / 500); - sx_init(&np->lock, "nvmft port"); + mtx_init(&np->lock, "nvmft port", NULL, MTX_DEF); np->ids = new_unrhdr(0, MIN(CTL_MAX_INIT_PER_PORT - 1, NVMF_CNTLID_STATIC_MAX), UNR_NO_MTX); TAILQ_INIT(&np->controllers); @@ -915,12 +923,12 @@ nvmft_port_remove(struct ctl_req *req) TAILQ_REMOVE(&nvmft_ports, np, link); sx_xunlock(&nvmft_ports_lock); - sx_slock(&np->lock); + mtx_lock(&np->lock); if (np->online) { - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); ctl_port_offline(&np->port); } else - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_port_rele(np); req->status = CTL_LUN_OK; @@ -1058,7 +1066,7 @@ nvmft_list(struct ctl_nvmf *cn) sbuf_printf(sb, "\n"); sx_slock(&nvmft_ports_lock); TAILQ_FOREACH(np, &nvmft_ports, link) { - sx_slock(&np->lock); + mtx_lock(&np->lock); TAILQ_FOREACH(ctrlr, &np->controllers, link) { sbuf_printf(sb, "" "%s" @@ -1070,7 +1078,7 @@ nvmft_list(struct ctl_nvmf *cn) np->cdata.subnqn, ctrlr->trtype); } - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); } sx_sunlock(&nvmft_ports_lock); sbuf_printf(sb, "\n"); @@ -1108,7 +1116,7 @@ nvmft_terminate(struct ctl_nvmf *cn) found = false; sx_slock(&nvmft_ports_lock); TAILQ_FOREACH(np, &nvmft_ports, link) { - sx_slock(&np->lock); + mtx_lock(&np->lock); TAILQ_FOREACH(ctrlr, &np->controllers, link) { if (tp->all != 0) match = true; @@ -1126,7 +1134,7 @@ nvmft_terminate(struct ctl_nvmf *cn) nvmft_controller_error(ctrlr, NULL, ECONNABORTED); found = true; } - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); } sx_sunlock(&nvmft_ports_lock); diff --git a/sys/dev/nvmf/controller/nvmft_controller.c b/sys/dev/nvmf/controller/nvmft_controller.c index 83a156d9b92a..96c9fee47357 100644 --- a/sys/dev/nvmf/controller/nvmft_controller.c +++ b/sys/dev/nvmf/controller/nvmft_controller.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -55,8 +54,6 @@ nvmft_controller_alloc(struct nvmft_port *np, uint16_t cntlid, ctrlr = malloc(sizeof(*ctrlr), M_NVMFT, M_WAITOK | M_ZERO); ctrlr->cntlid = cntlid; - nvmft_port_ref(np); - TAILQ_INSERT_TAIL(&np->controllers, ctrlr, link); ctrlr->np = np; mtx_init(&ctrlr->lock, "nvmft controller", NULL, MTX_DEF); callout_init(&ctrlr->ka_timer, 1); @@ -126,10 +123,10 @@ nvmft_handoff_admin_queue(struct nvmft_port *np, enum nvmf_trtype trtype, return (ENXIO); } - sx_xlock(&np->lock); + mtx_lock(&np->lock); cntlid = alloc_unr(np->ids); if (cntlid == -1) { - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); printf("NVMFT: Unable to allocate controller for %.*s\n", (int)sizeof(data->hostnqn), data->hostnqn); nvmft_connect_error(qp, cmd, NVME_SCT_COMMAND_SPECIFIC, @@ -144,8 +141,21 @@ nvmft_handoff_admin_queue(struct nvmft_port *np, enum nvmf_trtype trtype, ("%s: duplicate controllers with id %d", __func__, cntlid)); } #endif + mtx_unlock(&np->lock); ctrlr = nvmft_controller_alloc(np, cntlid, data); + + mtx_lock(&np->lock); + if (!np->online) { + mtx_unlock(&np->lock); + nvmft_controller_free(ctrlr); + free_unr(np->ids, cntlid); + nvmft_qpair_destroy(qp); + return (ENXIO); + } + nvmft_port_ref(np); + TAILQ_INSERT_TAIL(&np->controllers, ctrlr, link); + nvmft_printf(ctrlr, "associated with %.*s\n", (int)sizeof(data->hostnqn), data->hostnqn); ctrlr->admin = qp; @@ -165,9 +175,9 @@ nvmft_handoff_admin_queue(struct nvmft_port *np, enum nvmf_trtype trtype, callout_reset_sbt(&ctrlr->ka_timer, ctrlr->ka_sbt, 0, nvmft_keep_alive_timer, ctrlr, C_HARDCLOCK); } + mtx_unlock(&np->lock); nvmft_finish_accept(qp, cmd, ctrlr); - sx_xunlock(&np->lock); return (0); } @@ -195,13 +205,13 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, return (ENXIO); } - sx_slock(&np->lock); + mtx_lock(&np->lock); TAILQ_FOREACH(ctrlr, &np->controllers, link) { if (ctrlr->cntlid == cntlid) break; } if (ctrlr == NULL) { - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); printf("NVMFT: Nonexistent controller %u for I/O queue %u from %.*s\n", ctrlr->cntlid, qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -212,7 +222,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, } if (memcmp(ctrlr->hostid, data->hostid, sizeof(ctrlr->hostid)) != 0) { - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "hostid mismatch for I/O queue %u from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -222,7 +232,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, return (EINVAL); } if (memcmp(ctrlr->hostnqn, data->hostnqn, sizeof(ctrlr->hostnqn)) != 0) { - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "hostnqn mismatch for I/O queue %u from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -237,7 +247,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, mtx_lock(&ctrlr->lock); if (ctrlr->shutdown) { mtx_unlock(&ctrlr->lock); - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "attempt to create I/O queue %u on disabled controller from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -248,7 +258,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, } if (ctrlr->num_io_queues == 0) { mtx_unlock(&ctrlr->lock); - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "attempt to create I/O queue %u without enabled queues from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -259,7 +269,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, } if (cmd->qid > ctrlr->num_io_queues) { mtx_unlock(&ctrlr->lock); - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "attempt to create invalid I/O queue %u from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -270,7 +280,7 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, } if (ctrlr->io_qpairs[qid - 1].qp != NULL) { mtx_unlock(&ctrlr->lock); - sx_sunlock(&np->lock); + mtx_unlock(&np->lock); nvmft_printf(ctrlr, "attempt to re-create I/O queue %u from %.*s\n", qid, (int)sizeof(data->hostnqn), data->hostnqn); @@ -282,8 +292,8 @@ nvmft_handoff_io_queue(struct nvmft_port *np, enum nvmf_trtype trtype, ctrlr->io_qpairs[qid - 1].qp = qp; mtx_unlock(&ctrlr->lock); + mtx_unlock(&np->lock); nvmft_finish_accept(qp, cmd, ctrlr); - sx_sunlock(&np->lock); return (0); } @@ -382,11 +392,11 @@ nvmft_controller_terminate(void *arg, int pending) /* Remove association (CNTLID). */ np = ctrlr->np; - sx_xlock(&np->lock); + mtx_lock(&np->lock); TAILQ_REMOVE(&np->controllers, ctrlr, link); - free_unr(np->ids, ctrlr->cntlid); wakeup_np = (!np->online && TAILQ_EMPTY(&np->controllers)); - sx_xunlock(&np->lock); + mtx_unlock(&np->lock); + free_unr(np->ids, ctrlr->cntlid); if (wakeup_np) wakeup(np); diff --git a/sys/dev/nvmf/controller/nvmft_var.h b/sys/dev/nvmf/controller/nvmft_var.h index 7a1748d5999e..6d20e2c8ac11 100644 --- a/sys/dev/nvmf/controller/nvmft_var.h +++ b/sys/dev/nvmf/controller/nvmft_var.h @@ -35,7 +35,7 @@ struct nvmft_port { uint32_t max_io_qsize; bool online; - struct sx lock; + struct mtx lock; struct unrhdr *ids; TAILQ_HEAD(, nvmft_controller) controllers;