Module Name:    src
Committed By:   jdolecek
Date:           Tue Nov  1 14:24:36 UTC 2016

Modified Files:
        src/sys/dev/ic: nvme.c nvmevar.h

Log Message:
tighter queue control - according to spec actual cap on number of commands
in flight is actually one less then queue size, head == tail means empty
queue


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/dev/ic/nvme.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/ic/nvmevar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/nvme.c
diff -u src/sys/dev/ic/nvme.c:1.19 src/sys/dev/ic/nvme.c:1.20
--- src/sys/dev/ic/nvme.c:1.19	Thu Oct 20 19:20:40 2016
+++ src/sys/dev/ic/nvme.c	Tue Nov  1 14:24:35 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvme.c,v 1.19 2016/10/20 19:20:40 jdolecek Exp $	*/
+/*	$NetBSD: nvme.c,v 1.20 2016/11/01 14:24:35 jdolecek Exp $	*/
 /*	$OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.19 2016/10/20 19:20:40 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.20 2016/11/01 14:24:35 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -58,7 +58,7 @@ static int	nvme_identify(struct nvme_sof
 static void	nvme_fill_identify(struct nvme_queue *, struct nvme_ccb *,
 		    void *);
 
-static int	nvme_ccbs_alloc(struct nvme_queue *, u_int);
+static int	nvme_ccbs_alloc(struct nvme_queue *, uint16_t);
 static void	nvme_ccbs_free(struct nvme_queue *);
 
 static struct nvme_ccb *
@@ -333,8 +333,8 @@ nvme_attach(struct nvme_softc *sc)
 	uint32_t reg;
 	u_int dstrd;
 	u_int mps = PAGE_SHIFT;
-	int adminq_entries = nvme_adminq_size;
-	int ioq_entries = nvme_ioq_size;
+	uint16_t adminq_entries = nvme_adminq_size;
+	uint16_t ioq_entries = nvme_ioq_size;
 	int i;
 
 	reg = nvme_read4(sc, NVME_VS);
@@ -1079,7 +1079,8 @@ nvme_q_complete(struct nvme_softc *sc, s
 			/* NOTREACHED */
 		}
 #endif
-		rv = 1;
+
+		rv++;
 
 		/*
 		 * Unlock the mutex before calling the ccb_done callback
@@ -1098,6 +1099,12 @@ nvme_q_complete(struct nvme_softc *sc, s
 
 	mutex_exit(&q->q_cq_mtx);
 
+	if (rv) {
+		mutex_enter(&q->q_ccb_mtx);
+		q->q_nccbs_avail += rv;
+		mutex_exit(&q->q_ccb_mtx);
+	}
+
 	return rv;
 }
 
@@ -1263,7 +1270,7 @@ nvme_fill_identify(struct nvme_queue *q,
 }
 
 static int
-nvme_ccbs_alloc(struct nvme_queue *q, u_int nccbs)
+nvme_ccbs_alloc(struct nvme_queue *q, uint16_t nccbs)
 {
 	struct nvme_softc *sc = q->q_sc;
 	struct nvme_ccb *ccb;
@@ -1279,6 +1286,7 @@ nvme_ccbs_alloc(struct nvme_queue *q, u_
 		return 1;
 
 	q->q_nccbs = nccbs;
+	q->q_nccbs_avail = nccbs;
 	q->q_ccb_prpls = nvme_dmamem_alloc(sc,
 	    sizeof(*prpl) * sc->sc_max_sgl * nccbs);
 
@@ -1315,11 +1323,14 @@ free_maps:
 static struct nvme_ccb *
 nvme_ccb_get(struct nvme_queue *q)
 {
-	struct nvme_ccb *ccb;
+	struct nvme_ccb *ccb = NULL;
 
 	mutex_enter(&q->q_ccb_mtx);
-	ccb = SIMPLEQ_FIRST(&q->q_ccb_list);
-	if (ccb != NULL) {
+	if (q->q_nccbs_avail > 0) {
+		ccb = SIMPLEQ_FIRST(&q->q_ccb_list);
+		KASSERT(ccb != NULL);
+		q->q_nccbs_avail--;
+
 		SIMPLEQ_REMOVE_HEAD(&q->q_ccb_list, ccb_entry);
 #ifdef DEBUG
 		ccb->ccb_cookie = NULL;
@@ -1397,7 +1408,12 @@ nvme_q_alloc(struct nvme_softc *sc, uint
 	nvme_dmamem_sync(sc, q->q_sq_dmamem, BUS_DMASYNC_PREWRITE);
 	nvme_dmamem_sync(sc, q->q_cq_dmamem, BUS_DMASYNC_PREREAD);
 
-	if (nvme_ccbs_alloc(q, entries) != 0) {
+	/*
+	 * Due to definition of full and empty queue (queue is empty
+	 * when head == tail, full when tail is one less then head),
+	 * we can actually only have (entries - 1) in-flight commands.
+	 */
+	if (nvme_ccbs_alloc(q, entries - 1) != 0) {
 		aprint_error_dev(sc->sc_dev, "unable to allocate ccbs\n");
 		goto free_cq;
 	}

Index: src/sys/dev/ic/nvmevar.h
diff -u src/sys/dev/ic/nvmevar.h:1.9 src/sys/dev/ic/nvmevar.h:1.10
--- src/sys/dev/ic/nvmevar.h:1.9	Thu Oct 20 19:20:40 2016
+++ src/sys/dev/ic/nvmevar.h	Tue Nov  1 14:24:35 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nvmevar.h,v 1.9 2016/10/20 19:20:40 jdolecek Exp $	*/
+/*	$NetBSD: nvmevar.h,v 1.10 2016/11/01 14:24:35 jdolecek Exp $	*/
 /*	$OpenBSD: nvmevar.h,v 1.8 2016/04/14 11:18:32 dlg Exp $ */
 
 /*
@@ -86,7 +86,8 @@ struct nvme_queue {
 	uint16_t		q_cq_phase;
 
 	kmutex_t		q_ccb_mtx;
-	u_int			q_nccbs;
+	uint16_t		q_nccbs;	/* total number of ccbs */
+	uint16_t		q_nccbs_avail;	/* available ccbs */
 	struct nvme_ccb		*q_ccbs;
 	SIMPLEQ_HEAD(, nvme_ccb) q_ccb_list;
 	struct nvme_dmamem	*q_ccb_prpls;

Reply via email to