git: 4a3a5de8ace3 - main - nda: Update trim stats with the periph lock held
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 06 Oct 2026 22:58:49 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=4a3a5de8ace3c41da35f0fbac4d2549b868d1091
commit 4a3a5de8ace3c41da35f0fbac4d2549b868d1091
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-10-06 22:45:36 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-10-06 22:46:22 +0000
nda: Update trim stats with the periph lock held
Separate the updating the stats for the completion from the biodone for
each one.
Sponsored by: Netflix
Reviewed by: ali_mashtizadeh.com
Differential Revision: https://reviews.freebsd.org/D60155
---
sys/cam/cam_iosched.c | 22 ++++++++++++++++++++++
sys/cam/cam_iosched.h | 2 ++
sys/cam/nvme/nvme_da.c | 22 ++++------------------
3 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/sys/cam/cam_iosched.c b/sys/cam/cam_iosched.c
index e807301c6302..822adffc93e5 100644
--- a/sys/cam/cam_iosched.c
+++ b/sys/cam/cam_iosched.c
@@ -1822,6 +1822,28 @@ cam_iosched_bio_update_stats(struct cam_iosched_softc *isc, struct bio *bp,
return retval;
}
+/*
+ * Update completion status and statistics for each bio in a queue.
+ * The queue is not modified.
+ */
+void
+cam_iosched_bio_queue_update_stats(struct cam_iosched_softc *isc,
+ struct bio_queue *queue, union ccb *done_ccb, int error)
+{
+ struct bio *bp;
+
+ TAILQ_FOREACH(bp, queue, bio_queue) {
+ bp->bio_error = error;
+ if (error != 0) {
+ bp->bio_flags |= BIO_ERROR;
+ bp->bio_resid = bp->bio_bcount;
+ } else
+ bp->bio_resid = 0;
+ cam_iosched_bio_update_stats(isc, bp, done_ccb);
+ done_ccb = NULL;
+ }
+}
+
/*
* Tell the io scheduler that you've pushed a trim down into the sim.
* This also tells the I/O scheduler not to push any more trims down, so
diff --git a/sys/cam/cam_iosched.h b/sys/cam/cam_iosched.h
index cbe6a20fb871..9fc9d4a91b22 100644
--- a/sys/cam/cam_iosched.h
+++ b/sys/cam/cam_iosched.h
@@ -100,6 +100,8 @@ void cam_iosched_set_work_flags(struct cam_iosched_softc *isc, uint32_t flags);
void cam_iosched_clr_work_flags(struct cam_iosched_softc *isc, uint32_t flags);
void cam_iosched_trim_done(struct cam_iosched_softc *isc);
int cam_iosched_bio_update_stats(struct cam_iosched_softc *isc, struct bio *bp, union ccb *done_ccb);
+void cam_iosched_bio_queue_update_stats(struct cam_iosched_softc *isc,
+ struct bio_queue *queue, union ccb *done_ccb, int error);
void cam_iosched_set_latfcn(struct cam_iosched_softc *isc, cam_iosched_latfcn_t, void *);
void cam_iosched_set_trim_goal(struct cam_iosched_softc *isc, int goal);
void cam_iosched_set_trim_ticks(struct cam_iosched_softc *isc, int ticks);
diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index fe5c87c5428a..dc06d2d0d0ab 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -1329,8 +1329,8 @@ ndadone(struct cam_periph *periph, union ccb *done_ccb)
biodone(bp);
} else { /* state == NDA_CCB_TRIM */
struct nda_trim_request *trim;
- struct bio *bp1, *bp2;
- TAILQ_HEAD(, bio) queue;
+ struct bio *bp2;
+ struct bio_queue queue;
trim = nvmeio->ccb_trim;
TAILQ_INIT(&queue);
@@ -1342,28 +1342,14 @@ ndadone(struct cam_periph *periph, union ccb *done_ccb)
* need to call this here.
* cam_iosched_trim_done(softc->cam_iosched);
*/
- /*
- * The the I/O scheduler that we're finishing the I/O
- * so we can keep book. The first one we pass in the CCB
- * which has the timing information. The rest we pass in NULL
- * so we can keep proper counts.
- */
- bp1 = TAILQ_FIRST(&queue);
- cam_iosched_bio_update_stats(softc->cam_iosched, bp1, done_ccb);
+ cam_iosched_bio_queue_update_stats(softc->cam_iosched,
+ &queue, done_ccb, error);
xpt_release_ccb(done_ccb);
softc->outstanding_cmds--;
ndaschedule(periph);
cam_periph_unlock(periph);
while ((bp2 = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, bp2, bio_queue);
- bp2->bio_error = error;
- if (error != 0) {
- bp2->bio_flags |= BIO_ERROR;
- bp2->bio_resid = bp1->bio_bcount;
- } else
- bp2->bio_resid = 0;
- if (bp1 != bp2)
- cam_iosched_bio_update_stats(softc->cam_iosched, bp2, NULL);
biodone(bp2);
}
}