From nobody Wed Dec 10 22:53:51 2025 X-Original-To: dev-commits-src-main@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 4dRWH43Nlcz6Jq7Z for ; Wed, 10 Dec 2025 22:53:52 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dRWH35z3nz3PST for ; Wed, 10 Dec 2025 22:53:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1765407231; 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=BISpXwktCj8u1b+sWLpEX7CAS24QdGNYpYT1FGHn6mU=; b=xdzQg58eTLcOv57hNX80xEmlb1XO2htrRb0wQ7rsgdOhZtTNXqqA7iGIqe456jy9yGzrDz UiTCoUFNUYAgLKY0DnJcdPl9rm+fD/fNYwck0xoThQ2FnkhPnWB25h7C/RrfcA0fPUE5jY i5cuxD95LY30oL3rPrk/H0hc+fr7JlwIqyZ6Ni3GXe5/6iTjwdz4XO2IhZ78o7U8AV56Hq o7pyvKh3LcmXM2FUa6vUWqOp5KV8iU0mJ+ZoMoAG9uVtcft32r1Ymll0h1HePR251wo0fO 9dXAxir9mj9cb9zO0X4G5el/IfKg+HoA+dSHSxPqZWa+cYi/m/b7BLk7xT80PQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1765407231; 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=BISpXwktCj8u1b+sWLpEX7CAS24QdGNYpYT1FGHn6mU=; b=FRadbmjhX6RQ3pz3HMfo/0GsrT2OI0hdNj3tHgWqDwYbv9tfhzXJvXnOmo8LQqrxdr37e5 uIC+QuF1O8VEwUkyVd2rapxEIN/pV017kxIEK/QgMwa98brDUmKJJCzq6ItOtToiLEfBVQ Bonw8PFE70YCdH6EkNo52HaY0r2awERR6cXAowTvdMrKfgeB+QeSt/lXE1zNjtRT/+Qcji GL5KeaSRWGzQtRqIB8koiGGY3ETllCR5D7q0txHNHSVC1HuTtCdFt/faklYN/fn244HZsN OJ0I0ZoVJ+Y5UgW4n831cZo1AIadKhj78E4bu1Siyr40oMMnbcskK2fH5gs38g== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1765407231; a=rsa-sha256; cv=none; b=uTEG5JCoFNoOlNdAFuPtPL+3V2+Fkqwo/H5g5/MsY+QrUkvBCJHk3czDA9d672w/fZlToJ wTia6V9wmlEwrmaifEReGfjrImrueFS596naCphrCL4ckmGFKrCPabWN8qMQseV3Vzp2SA loozL+i2dv5RNtQKPnHMShoYUXHXfbwUyff7zXwq4nkWJbfxEJ2QEaZ8nb91+iMX7Drd8h 2JfU9sk2HcxbyYXlhe1JbL4QM3K1bBRaQPh/GJp67luOTYPaW3sK/vhbQDvJ82imUXXKzF lzSIPQjt6vZ52+l/Iik5sAkEWzzjIail2MKBI90b6hp6BVJQEbO5AdVbA5k8lA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dRWH33vlsz14hx for ; Wed, 10 Dec 2025 22:53:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id b819 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 10 Dec 2025 22:53:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: 1e39b5d4833e - main - nvme_sim: Attach as a child of nvme List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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: 1e39b5d4833e3be0261ff9cc2d360aa36698c3dc Auto-Submitted: auto-generated Date: Wed, 10 Dec 2025 22:53:51 +0000 Message-Id: <6939f9ff.b819.65552ec6@gitrepo.freebsd.org> The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=1e39b5d4833e3be0261ff9cc2d360aa36698c3dc commit 1e39b5d4833e3be0261ff9cc2d360aa36698c3dc Author: Warner Losh AuthorDate: 2025-12-10 22:52:23 +0000 Commit: Warner Losh CommitDate: 2025-12-10 22:52:23 +0000 nvme_sim: Attach as a child of nvme Rather than registering as a consumer of the nvme controller, hook into the child device and use that. This is a small regression at the moment: we don't fail the device when that happens at runtime, and we don't handle new namespaces when they arrive (though that feature is currently fragile). Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D51384 --- sys/dev/nvme/nvme_sim.c | 138 +++++++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 53 deletions(-) diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index e015fbe4d072..88d777f556ed 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -304,61 +304,101 @@ nvme_sim_poll(struct cam_sim *sim) nvme_ctrlr_poll(sim2ctrlr(sim)); } -static void * -nvme_sim_new_controller(struct nvme_controller *ctrlr) +static void +nvme_sim_ns_change(struct nvme_namespace *ns, struct nvme_sim_softc *sc) +{ + union ccb *ccb; + + /* + * We map the NVMe namespace idea onto the CAM unit LUN. For each new + * namespace, we create a new CAM path for it. We then rescan the path + * to get it to enumerate. + */ + ccb = xpt_alloc_ccb(); + if (xpt_create_path(&ccb->ccb_h.path, /*periph*/NULL, + cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { + printf("unable to create path for rescan\n"); + xpt_free_ccb(ccb); + return; + } + xpt_rescan(ccb); +} + +static int +nvme_sim_probe(device_t dev) +{ + if (nvme_use_nvd) + return (ENXIO); + + device_set_desc(dev, "nvme cam"); + return (BUS_PROBE_DEFAULT); +} + +static int +nvme_sim_attach(device_t dev) { - struct nvme_sim_softc *sc; struct cam_devq *devq; int max_trans; + int err = ENOMEM; + struct nvme_sim_softc *sc = device_get_softc(dev); + struct nvme_controller *ctrlr = device_get_ivars(dev); max_trans = ctrlr->max_hw_pend_io; devq = cam_simq_alloc(max_trans); if (devq == NULL) - return (NULL); + return (ENOMEM); - sc = malloc(sizeof(*sc), M_NVME, M_ZERO | M_WAITOK); sc->s_ctrlr = ctrlr; sc->s_sim = cam_sim_alloc(nvme_sim_action, nvme_sim_poll, - "nvme", sc, device_get_unit(ctrlr->dev), + "nvme", sc, device_get_unit(dev), NULL, max_trans, max_trans, devq); if (sc->s_sim == NULL) { - printf("Failed to allocate a sim\n"); + device_printf(dev, "Failed to allocate a sim\n"); cam_simq_free(devq); goto err1; } - if (xpt_bus_register(sc->s_sim, ctrlr->dev, 0) != CAM_SUCCESS) { - printf("Failed to create a bus\n"); + if (xpt_bus_register(sc->s_sim, dev, 0) != CAM_SUCCESS) { + err = ENXIO; + device_printf(dev, "Failed to create a bus\n"); goto err2; } if (xpt_create_path(&sc->s_path, /*periph*/NULL, cam_sim_path(sc->s_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - printf("Failed to create a path\n"); + err = ENXIO; + device_printf(dev, "Failed to create a path\n"); goto err3; } - return (sc); + for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + struct nvme_namespace *ns = &ctrlr->ns[i]; + + if (ns->data.nsze == 0) + continue; + nvme_sim_ns_change(ns, sc); + } + return (0); err3: xpt_bus_deregister(cam_sim_path(sc->s_sim)); err2: cam_sim_free(sc->s_sim, /*free_devq*/TRUE); err1: free(sc, M_NVME); - return (NULL); + return (err); } -static void * -nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg) +static int +nvme_sim_fail(device_t dev, struct nvme_namespace *ns) { - struct nvme_sim_softc *sc = sc_arg; + struct nvme_sim_softc *sc = device_get_softc(dev); struct cam_path *tmppath; union ccb *ccb; if (xpt_create_path(&tmppath, /*periph*/NULL, cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { - printf("unable to create path for rescan\n"); - return (NULL); + device_printf(dev, "unable to create path for rescan\n"); + return (ENOMEM); } /* * If it's gone, then signal that and leave. @@ -366,13 +406,13 @@ nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg) if (ns->flags & NVME_NS_GONE) { xpt_async(AC_LOST_DEVICE, tmppath, NULL); xpt_free_path(tmppath); - return (sc_arg); + return (0); } ccb = xpt_alloc_ccb_nowait(); if (ccb == NULL) { - printf("unable to alloc CCB for rescan\n"); - return (NULL); + device_printf(dev, "unable to alloc CCB for rescan\n"); + return (ENOMEM); } ccb->ccb_h.path = tmppath; @@ -383,45 +423,37 @@ nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg) */ xpt_rescan(ccb); - return (sc_arg); + return (0); } -static void -nvme_sim_controller_fail(void *ctrlr_arg) +static int +nvme_sim_detach(device_t dev) { - struct nvme_sim_softc *sc = ctrlr_arg; + struct nvme_controller *ctrlr = device_get_ivars(dev); - xpt_async(AC_LOST_DEVICE, sc->s_path, NULL); - xpt_free_path(sc->s_path); - xpt_bus_deregister(cam_sim_path(sc->s_sim)); - cam_sim_free(sc->s_sim, /*free_devq*/TRUE); - free(sc, M_NVME); -} + for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + struct nvme_namespace *ns = &ctrlr->ns[i]; -struct nvme_consumer *consumer_cookie; - -static void -nvme_sim_init(void *dummy __unused) -{ - if (nvme_use_nvd) - return; - - consumer_cookie = nvme_register_consumer(nvme_sim_ns_change, - nvme_sim_new_controller, NULL, nvme_sim_controller_fail); + if (ns->data.nsze == 0) + continue; + nvme_sim_fail(dev, ns); + } + return (0); } -SYSINIT(nvme_sim_register, SI_SUB_DRIVERS, SI_ORDER_ANY, - nvme_sim_init, NULL); - -static void -nvme_sim_uninit(void *dummy __unused) -{ - if (nvme_use_nvd) - return; - /* XXX Cleanup */ +static device_method_t nvme_sim_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, nvme_sim_probe), + DEVMETHOD(device_attach, nvme_sim_attach), + DEVMETHOD(device_detach, nvme_sim_detach), + { 0, 0 } +}; - nvme_unregister_consumer(consumer_cookie); -} +static driver_t nvme_sim_driver = { + "nvme_sim", + nvme_sim_methods, + sizeof(struct nvme_sim_softc), +}; -SYSUNINIT(nvme_sim_unregister, SI_SUB_DRIVERS, SI_ORDER_ANY, - nvme_sim_uninit, NULL); +DRIVER_MODULE(nvme_sim, nvme, nvme_sim_driver, NULL, NULL); +MODULE_VERSION(nvme_shim, 1);