Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/ic nvme(4): Limit the number of queues to the number...
details: https://anonhg.NetBSD.org/src/rev/b00da39953b9
branches: trunk
changeset: 351442:b00da39953b9
user: nonaka <nonaka%NetBSD.org@localhost>
date: Mon Feb 13 11:10:45 2017 +0000
description:
nvme(4): Limit the number of queues to the number allocated in HW.
diffstat:
sys/dev/ic/nvme.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 52 insertions(+), 4 deletions(-)
diffs (105 lines):
diff -r 1e871745df09 -r b00da39953b9 sys/dev/ic/nvme.c
--- a/sys/dev/ic/nvme.c Mon Feb 13 10:37:37 2017 +0000
+++ b/sys/dev/ic/nvme.c Mon Feb 13 11:10:45 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nvme.c,v 1.22 2016/11/01 14:46:31 jdolecek Exp $ */
+/* $NetBSD: nvme.c,v 1.23 2017/02/13 11:10:45 nonaka 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.22 2016/11/01 14:46:31 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.23 2017/02/13 11:10:45 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -107,6 +107,8 @@
static int nvme_command_passthrough(struct nvme_softc *,
struct nvme_pt_command *, uint16_t, struct lwp *, bool);
+static int nvme_get_number_of_queues(struct nvme_softc *, u_int *);
+
#define NVME_TIMO_QOP 5 /* queue create and delete timeout */
#define NVME_TIMO_IDENT 10 /* probe identify timeout */
#define NVME_TIMO_PT -1 /* passthrough cmd timeout */
@@ -333,6 +335,7 @@
uint32_t reg;
u_int dstrd;
u_int mps = PAGE_SHIFT;
+ u_int ioq_allocated;
uint16_t adminq_entries = nvme_adminq_size;
uint16_t ioq_entries = nvme_ioq_size;
int i;
@@ -395,6 +398,17 @@
nvme_ccbs_free(sc->sc_admin_q);
nvme_ccbs_alloc(sc->sc_admin_q, sc->sc_admin_q->q_entries);
+ if (sc->sc_use_mq) {
+ /* Limit the number of queues to the number allocated in HW */
+ if (nvme_get_number_of_queues(sc, &ioq_allocated) != 0) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to get number of queues\n");
+ goto disable;
+ }
+ if (sc->sc_nq > ioq_allocated)
+ sc->sc_nq = ioq_allocated;
+ }
+
sc->sc_q = kmem_zalloc(sizeof(*sc->sc_q) * sc->sc_nq, KM_SLEEP);
if (sc->sc_q == NULL) {
aprint_error_dev(sc->sc_dev, "unable to allocate io queue\n");
@@ -868,8 +882,8 @@
bus_dmamap_unload(sc->sc_dmat, dmap);
}
- pt->cpl.cdw0 = cqe->cdw0;
- pt->cpl.flags = cqe->flags & ~NVME_CQE_PHASE;
+ pt->cpl.cdw0 = lemtoh32(&cqe->cdw0);
+ pt->cpl.flags = lemtoh16(&cqe->flags) & ~NVME_CQE_PHASE;
}
static int
@@ -1271,6 +1285,40 @@
}
static int
+nvme_get_number_of_queues(struct nvme_softc *sc, u_int *nqap)
+{
+ struct nvme_pt_command pt;
+ struct nvme_ccb *ccb;
+ uint16_t ncqa, nsqa;
+ int rv;
+
+ ccb = nvme_ccb_get(sc->sc_admin_q);
+ KASSERT(ccb != NULL); /* it's a bug if we don't have spare ccb here */
+
+ memset(&pt, 0, sizeof(pt));
+ pt.cmd.opcode = NVM_ADMIN_GET_FEATURES;
+ pt.cmd.cdw10 = 7 /*NVME_FEAT_NUMBER_OF_QUEUES*/;
+
+ ccb->ccb_done = nvme_pt_done;
+ ccb->ccb_cookie = &pt;
+
+ rv = nvme_poll(sc, sc->sc_admin_q, ccb, nvme_pt_fill, NVME_TIMO_QOP);
+
+ nvme_ccb_put(sc->sc_admin_q, ccb);
+
+ if (rv != 0) {
+ *nqap = 0;
+ return EIO;
+ }
+
+ ncqa = pt.cpl.cdw0 >> 16;
+ nsqa = pt.cpl.cdw0 & 0xffff;
+ *nqap = MIN(ncqa, nsqa) + 1;
+
+ return 0;
+}
+
+static int
nvme_ccbs_alloc(struct nvme_queue *q, uint16_t nccbs)
{
struct nvme_softc *sc = q->q_sc;
Home |
Main Index |
Thread Index |
Old Index