Index: head/sys/cam/nvme/nvme_da.c =================================================================== --- head/sys/cam/nvme/nvme_da.c +++ head/sys/cam/nvme/nvme_da.c @@ -336,6 +336,8 @@ while (softc->refcount != 0) cam_periph_sleep(periph, &softc->refcount, PRIBIO, "ndaclose", 1); + KASSERT(softc->outstanding_cmds == 0, + ("nda %d outstanding commands", softc->outstanding_cmds)); cam_periph_unlock(periph); cam_periph_release(periph); return (0); @@ -986,10 +988,11 @@ out: start_ccb->ccb_h.flags |= CAM_UNLOCKED; softc->outstanding_cmds++; - softc->refcount++; + softc->refcount++; /* For submission only */ cam_periph_unlock(periph); xpt_action(start_ccb); cam_periph_lock(periph); + softc->refcount--; /* Submission done */ /* May have more work to do, so ensure we stay scheduled */ ndaschedule(periph); @@ -1085,6 +1088,7 @@ bp1 = TAILQ_FIRST(&queue); cam_iosched_bio_complete(softc->cam_iosched, bp1, done_ccb); xpt_release_ccb(done_ccb); + softc->outstanding_cmds--; ndaschedule(periph); cam_periph_unlock(periph); while ((bp2 = TAILQ_FIRST(&queue)) != NULL) { @@ -1100,11 +1104,6 @@ biodone(bp2); } } - /* - * Release the periph refcount taken in mdastart() for each CCB. - */ - KASSERT(softc->refcount >= 1, ("ndadone softc %p refcount %d", softc, softc->refcount)); - softc->refcount--; return; } case NDA_CCB_DUMP: