Date: Wed, 10 Dec 2025 22:53:53 +0000 From: Warner Losh <imp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: a21f12840f5f - main - nvme_sim: Connect to events broadcast with nvme_if Message-ID: <6939fa01.b117.36a8aca3@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=a21f12840f5f25d777920957ed8ba7362052eaa7 commit a21f12840f5f25d777920957ed8ba7362052eaa7 Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2025-12-10 22:52:33 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2025-12-10 22:52:33 +0000 nvme_sim: Connect to events broadcast with nvme_if Connect up the nvme_ns_* events. Copy code from old ways, as needed, and refactor a little. Sponsored by: Netflix Reviewed by: dab Differential Revision: https://reviews.freebsd.org/D51387 --- sys/dev/nvme/nvme_sim.c | 145 +++++++++++++++++++++++++++------------------- sys/modules/nvme/Makefile | 1 + 2 files changed, 85 insertions(+), 61 deletions(-) diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index 88d777f556ed..d134d1daafc3 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -44,10 +44,15 @@ #include "nvme_private.h" +#include "nvme_if.h" + #define ccb_accb_ptr spriv_ptr0 #define ccb_ctrlr_ptr spriv_ptr1 static void nvme_sim_action(struct cam_sim *sim, union ccb *ccb); static void nvme_sim_poll(struct cam_sim *sim); +static int nvme_sim_ns_added(device_t dev, struct nvme_namespace *ns); +static int nvme_sim_ns_changed(device_t dev, uint32_t nsid); +static int nvme_sim_ns_removed(device_t dev, struct nvme_namespace *ns); #define sim2softc(sim) ((struct nvme_sim_softc *)cam_sim_softc(sim)) #define sim2ctrlr(sim) (sim2softc(sim)->s_ctrlr) @@ -304,26 +309,6 @@ nvme_sim_poll(struct cam_sim *sim) nvme_ctrlr_poll(sim2ctrlr(sim)); } -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) { @@ -339,7 +324,7 @@ nvme_sim_attach(device_t dev) { struct cam_devq *devq; int max_trans; - int err = ENOMEM; + int err = ENXIO; struct nvme_sim_softc *sc = device_get_softc(dev); struct nvme_controller *ctrlr = device_get_ivars(dev); @@ -356,16 +341,14 @@ nvme_sim_attach(device_t dev) if (sc->s_sim == NULL) { device_printf(dev, "Failed to allocate a sim\n"); cam_simq_free(devq); - goto err1; + return (ENOMEM); } 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) { - err = ENXIO; device_printf(dev, "Failed to create a path\n"); goto err3; } @@ -375,7 +358,7 @@ nvme_sim_attach(device_t dev) if (ns->data.nsze == 0) continue; - nvme_sim_ns_change(ns, sc); + nvme_sim_ns_added(dev, ns); } return (0); @@ -383,69 +366,109 @@ 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 (err); } + static int -nvme_sim_fail(device_t dev, struct nvme_namespace *ns) +nvme_sim_fail_all_ns(device_t dev) { struct nvme_sim_softc *sc = device_get_softc(dev); - struct cam_path *tmppath; - union ccb *ccb; + struct nvme_controller *ctrlr = sc->s_ctrlr; - if (xpt_create_path(&tmppath, /*periph*/NULL, - cam_sim_path(sc->s_sim), 0, ns->id) != CAM_REQ_CMP) { - device_printf(dev, "unable to create path for rescan\n"); - return (ENOMEM); - } - /* - * If it's gone, then signal that and leave. - */ - if (ns->flags & NVME_NS_GONE) { - xpt_async(AC_LOST_DEVICE, tmppath, NULL); - xpt_free_path(tmppath); - return (0); - } + for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { + struct nvme_namespace *ns = &ctrlr->ns[i]; - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) { - device_printf(dev, "unable to alloc CCB for rescan\n"); - return (ENOMEM); + if (ns->data.nsze == 0) + continue; + nvme_sim_ns_removed(dev, ns); } - ccb->ccb_h.path = tmppath; + return (0); +} + +static int +nvme_sim_detach(device_t dev) +{ + return (nvme_sim_fail_all_ns(dev)); +} + +static int +nvme_sim_ns_added(device_t dev, struct nvme_namespace *ns) +{ + struct nvme_sim_softc *sc = device_get_softc(dev); + union ccb *ccb; /* * We map the NVMe namespace idea onto the CAM unit LUN. For each new - * namespace, scan or rescan the path to enumerate it. tmppath freed at - * end of scan. + * namespace, scan or rescan the path to enumerate it. */ + 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"); + return (ENOMEM); + } xpt_rescan(ccb); return (0); } static int -nvme_sim_detach(device_t dev) +nvme_sim_ns_removed(device_t dev, struct nvme_namespace *ns) { - struct nvme_controller *ctrlr = device_get_ivars(dev); - - for (int i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { - struct nvme_namespace *ns = &ctrlr->ns[i]; + struct nvme_sim_softc *sc = device_get_softc(dev); + struct cam_path *tmppath; - if (ns->data.nsze == 0) - continue; - nvme_sim_fail(dev, ns); + 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 (ENOMEM); } + xpt_async(AC_LOST_DEVICE, tmppath, NULL); + xpt_free_path(tmppath); + + return (0); +} + +static int +nvme_sim_ns_changed(device_t dev, uint32_t nsid) +{ + struct nvme_sim_softc *sc = device_get_softc(dev); + struct nvme_namespace *ns = &sc->s_ctrlr->ns[nsid - 1]; + + /* + * These wind up being the same. For a configured cam_ed, we generate + * AC_GETDEV_CHANGED, but for new one we do AC_FOUND_DEVICE, but the + * scan is the same. + */ + return (nvme_sim_ns_added(dev, ns)); +} + +static int +nvme_sim_controller_failed(device_t dev) +{ + return (nvme_sim_fail_all_ns(dev)); +} + +static int +nvme_sim_handle_aen(device_t dev, const struct nvme_completion *cpl, + uint32_t pg_nr, void *page, uint32_t page_len) +{ + /* Do nothing */ return (0); } 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), + DEVMETHOD(device_probe, nvme_sim_probe), + DEVMETHOD(device_attach, nvme_sim_attach), + DEVMETHOD(device_detach, nvme_sim_detach), + /* Nvme controller messages */ + DEVMETHOD(nvme_ns_added, nvme_sim_ns_added), + DEVMETHOD(nvme_ns_removed, nvme_sim_ns_removed), + DEVMETHOD(nvme_ns_changed, nvme_sim_ns_changed), + DEVMETHOD(nvme_controller_failed, nvme_sim_controller_failed), + DEVMETHOD(nvme_handle_aen, nvme_sim_handle_aen), { 0, 0 } }; diff --git a/sys/modules/nvme/Makefile b/sys/modules/nvme/Makefile index 936a28fa5de9..b10f5dd190bf 100644 --- a/sys/modules/nvme/Makefile +++ b/sys/modules/nvme/Makefile @@ -16,6 +16,7 @@ SRCS = nvme.c \ \ bus_if.h \ device_if.h \ + nvme_if.h \ opt_cam.h \ opt_nvme.h \ pci_if.h
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6939fa01.b117.36a8aca3>
