Page MenuHomeFreeBSD

D14261.diff
No OneTemporary

D14261.diff

Index: head/sys/dev/mpr/mpr.c
===================================================================
--- head/sys/dev/mpr/mpr.c
+++ head/sys/dev/mpr/mpr.c
@@ -382,7 +382,7 @@
static void
mpr_resize_queues(struct mpr_softc *sc)
{
- int reqcr, prireqcr;
+ u_int reqcr, prireqcr, maxio, sges_per_frame;
/*
* Size the queues. Since the reply queues always need one free
@@ -401,7 +401,61 @@
sc->num_replies = MIN(sc->max_replyframes + sc->max_evtframes,
sc->facts->MaxReplyDescriptorPostQueueDepth) - 1;
+ /* Store the request frame size in bytes rather than as 32bit words */
+ sc->reqframesz = sc->facts->IOCRequestFrameSize * 4;
+
/*
+ * Gen3 and beyond uses the IOCMaxChainSegmentSize from IOC Facts to
+ * get the size of a Chain Frame. Previous versions use the size as a
+ * Request Frame for the Chain Frame size. If IOCMaxChainSegmentSize
+ * is 0, use the default value. The IOCMaxChainSegmentSize is the
+ * number of 16-byte elelements that can fit in a Chain Frame, which is
+ * the size of an IEEE Simple SGE.
+ */
+ if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
+ sc->chain_seg_size =
+ htole16(sc->facts->IOCMaxChainSegmentSize);
+ if (sc->chain_seg_size == 0) {
+ sc->chain_frame_size = MPR_DEFAULT_CHAIN_SEG_SIZE *
+ MPR_MAX_CHAIN_ELEMENT_SIZE;
+ } else {
+ sc->chain_frame_size = sc->chain_seg_size *
+ MPR_MAX_CHAIN_ELEMENT_SIZE;
+ }
+ } else {
+ sc->chain_frame_size = sc->reqframesz;
+ }
+
+ /*
+ * Max IO Size is Page Size * the following:
+ * ((SGEs per frame - 1 for chain element) * Max Chain Depth)
+ * + 1 for no chain needed in last frame
+ *
+ * If user suggests a Max IO size to use, use the smaller of the
+ * user's value and the calculated value as long as the user's
+ * value is larger than 0. The user's value is in pages.
+ */
+ sges_per_frame = sc->chain_frame_size/sizeof(MPI2_IEEE_SGE_SIMPLE64)-1;
+ maxio = (sges_per_frame * sc->facts->MaxChainDepth + 1) * PAGE_SIZE;
+
+ /*
+ * If I/O size limitation requested then use it and pass up to CAM.
+ * If not, use MAXPHYS as an optimization hint, but report HW limit.
+ */
+ if (sc->max_io_pages > 0) {
+ maxio = min(maxio, sc->max_io_pages * PAGE_SIZE);
+ sc->maxio = maxio;
+ } else {
+ sc->maxio = maxio;
+ maxio = min(maxio, MAXPHYS);
+ }
+
+ sc->num_chains = (maxio / PAGE_SIZE + sges_per_frame - 2) /
+ sges_per_frame * reqcr;
+ if (sc->max_chains > 0 && sc->max_chains < sc->num_chains)
+ sc->num_chains = sc->max_chains;
+
+ /*
* Figure out the number of MSIx-based queues. If the firmware or
* user has done something crazy and not allowed enough credit for
* the queues to be useful then don't enable multi-queue.
@@ -1355,9 +1409,6 @@
struct mpr_chain *chain;
int i, rsize, nsegs;
- /* Store the request frame size in bytes rather than as 32bit words */
- sc->reqframesz = sc->facts->IOCRequestFrameSize * 4;
-
rsize = sc->reqframesz * sc->num_reqs;
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
@@ -1382,28 +1433,7 @@
bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize,
mpr_memaddr_cb, &sc->req_busaddr, 0);
- /*
- * Gen3 and beyond uses the IOCMaxChainSegmentSize from IOC Facts to
- * get the size of a Chain Frame. Previous versions use the size as a
- * Request Frame for the Chain Frame size. If IOCMaxChainSegmentSize
- * is 0, use the default value. The IOCMaxChainSegmentSize is the
- * number of 16-byte elelements that can fit in a Chain Frame, which is
- * the size of an IEEE Simple SGE.
- */
- if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
- sc->chain_seg_size =
- htole16(sc->facts->IOCMaxChainSegmentSize);
- if (sc->chain_seg_size == 0) {
- sc->chain_frame_size = MPR_DEFAULT_CHAIN_SEG_SIZE *
- MPR_MAX_CHAIN_ELEMENT_SIZE;
- } else {
- sc->chain_frame_size = sc->chain_seg_size *
- MPR_MAX_CHAIN_ELEMENT_SIZE;
- }
- } else {
- sc->chain_frame_size = sc->reqframesz;
- }
- rsize = sc->chain_frame_size * sc->max_chains;
+ rsize = sc->chain_frame_size * sc->num_chains;
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
@@ -1451,13 +1481,13 @@
bus_dmamap_load(sc->sense_dmat, sc->sense_map, sc->sense_frames, rsize,
mpr_memaddr_cb, &sc->sense_busaddr, 0);
- sc->chains = malloc(sizeof(struct mpr_chain) * sc->max_chains, M_MPR,
+ sc->chains = malloc(sizeof(struct mpr_chain) * sc->num_chains, M_MPR,
M_WAITOK | M_ZERO);
if (!sc->chains) {
mpr_dprint(sc, MPR_ERROR, "Cannot allocate chain memory\n");
return (ENOMEM);
}
- for (i = 0; i < sc->max_chains; i++) {
+ for (i = 0; i < sc->num_chains; i++) {
chain = &sc->chains[i];
chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames +
i * sc->chain_frame_size);
@@ -1477,8 +1507,7 @@
return (ENOMEM);
}
- /* XXX Need to pick a more precise value */
- nsegs = (MAXPHYS / PAGE_SIZE) + 1;
+ nsegs = (sc->maxio / PAGE_SIZE) + 1;
if (bus_dma_tag_create( sc->mpr_parent_dmat, /* parent */
1, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
Index: head/sys/dev/mpr/mpr_sas.c
===================================================================
--- head/sys/dev/mpr/mpr_sas.c
+++ head/sys/dev/mpr/mpr_sas.c
@@ -1009,7 +1009,6 @@
{
struct ccb_pathinq *cpi = &ccb->cpi;
struct mpr_softc *sc = sassc->sc;
- uint8_t sges_per_frame;
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
@@ -1043,24 +1042,7 @@
cpi->transport_version = 0;
cpi->protocol = PROTO_SCSI;
cpi->protocol_version = SCSI_REV_SPC;
-
- /*
- * Max IO Size is Page Size * the following:
- * ((SGEs per frame - 1 for chain element) *
- * Max Chain Depth) + 1 for no chain needed in last frame
- *
- * If user suggests a Max IO size to use, use the smaller of the
- * user's value and the calculated value as long as the user's
- * value is larger than 0. The user's value is in pages.
- */
- sges_per_frame = (sc->chain_frame_size /
- sizeof(MPI2_IEEE_SGE_SIMPLE64)) - 1;
- cpi->maxio = (sges_per_frame * sc->facts->MaxChainDepth) + 1;
- cpi->maxio *= PAGE_SIZE;
- if ((sc->max_io_pages > 0) && (sc->max_io_pages * PAGE_SIZE <
- cpi->maxio))
- cpi->maxio = sc->max_io_pages * PAGE_SIZE;
- sc->maxio = cpi->maxio;
+ cpi->maxio = sc->maxio;
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
}
Index: head/sys/dev/mpr/mprvar.h
===================================================================
--- head/sys/dev/mpr/mprvar.h
+++ head/sys/dev/mpr/mprvar.h
@@ -361,6 +361,7 @@
int num_reqs;
int num_prireqs;
int num_replies;
+ int num_chains;
int fqdepth; /* Free queue */
int pqdepth; /* Post queue */
Index: head/sys/dev/mps/mps.c
===================================================================
--- head/sys/dev/mps/mps.c
+++ head/sys/dev/mps/mps.c
@@ -379,8 +379,8 @@
static void
mps_resize_queues(struct mps_softc *sc)
{
- int reqcr, prireqcr;
-
+ u_int reqcr, prireqcr, maxio, sges_per_frame;
+
/*
* Size the queues. Since the reply queues always need one free
* entry, we'll deduct one reply message here. The LSI documents
@@ -398,7 +398,39 @@
sc->num_replies = MIN(sc->max_replyframes + sc->max_evtframes,
sc->facts->MaxReplyDescriptorPostQueueDepth) - 1;
+ /* Store the request frame size in bytes rather than as 32bit words */
+ sc->reqframesz = sc->facts->IOCRequestFrameSize * 4;
+
/*
+ * Max IO Size is Page Size * the following:
+ * ((SGEs per frame - 1 for chain element) * Max Chain Depth)
+ * + 1 for no chain needed in last frame
+ *
+ * If user suggests a Max IO size to use, use the smaller of the
+ * user's value and the calculated value as long as the user's
+ * value is larger than 0. The user's value is in pages.
+ */
+ sges_per_frame = sc->reqframesz / sizeof(MPI2_SGE_SIMPLE64) - 1;
+ maxio = (sges_per_frame * sc->facts->MaxChainDepth + 1) * PAGE_SIZE;
+
+ /*
+ * If I/O size limitation requested, then use it and pass up to CAM.
+ * If not, use MAXPHYS as an optimization hint, but report HW limit.
+ */
+ if (sc->max_io_pages > 0) {
+ maxio = min(maxio, sc->max_io_pages * PAGE_SIZE);
+ sc->maxio = maxio;
+ } else {
+ sc->maxio = maxio;
+ maxio = min(maxio, MAXPHYS);
+ }
+
+ sc->num_chains = (maxio / PAGE_SIZE + sges_per_frame - 2) /
+ sges_per_frame * reqcr;
+ if (sc->max_chains > 0 && sc->max_chains < sc->num_chains)
+ sc->num_chains = sc->max_chains;
+
+ /*
* Figure out the number of MSIx-based queues. If the firmware or
* user has done something crazy and not allowed enough credit for
* the queues to be useful then don't enable multi-queue.
@@ -1334,9 +1366,6 @@
struct mps_chain *chain;
int i, rsize, nsegs;
- /* Store the request frame size in bytes rather than as 32bit words */
- sc->reqframesz = sc->facts->IOCRequestFrameSize * 4;
-
rsize = sc->reqframesz * sc->num_reqs;
if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
@@ -1361,7 +1390,7 @@
bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize,
mps_memaddr_cb, &sc->req_busaddr, 0);
- rsize = sc->reqframesz * sc->max_chains;
+ rsize = sc->reqframesz * sc->num_chains;
if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */
16, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
@@ -1409,13 +1438,13 @@
bus_dmamap_load(sc->sense_dmat, sc->sense_map, sc->sense_frames, rsize,
mps_memaddr_cb, &sc->sense_busaddr, 0);
- sc->chains = malloc(sizeof(struct mps_chain) * sc->max_chains, M_MPT2,
+ sc->chains = malloc(sizeof(struct mps_chain) * sc->num_chains, M_MPT2,
M_WAITOK | M_ZERO);
if(!sc->chains) {
mps_dprint(sc, MPS_ERROR, "Cannot allocate chains memory\n");
return (ENOMEM);
}
- for (i = 0; i < sc->max_chains; i++) {
+ for (i = 0; i < sc->num_chains; i++) {
chain = &sc->chains[i];
chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames +
i * sc->reqframesz);
@@ -1425,8 +1454,7 @@
sc->chain_free_lowwater++;
}
- /* XXX Need to pick a more precise value */
- nsegs = (MAXPHYS / PAGE_SIZE) + 1;
+ nsegs = (sc->maxio / PAGE_SIZE) + 1;
if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */
1, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
Index: head/sys/dev/mps/mps_sas.c
===================================================================
--- head/sys/dev/mps/mps_sas.c
+++ head/sys/dev/mps/mps_sas.c
@@ -958,7 +958,6 @@
{
struct ccb_pathinq *cpi = &ccb->cpi;
struct mps_softc *sc = sassc->sc;
- uint8_t sges_per_frame;
cpi->version_num = 1;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
@@ -987,23 +986,7 @@
cpi->transport_version = 0;
cpi->protocol = PROTO_SCSI;
cpi->protocol_version = SCSI_REV_SPC;
-
- /*
- * Max IO Size is Page Size * the following:
- * ((SGEs per frame - 1 for chain element) *
- * Max Chain Depth) + 1 for no chain needed in last frame
- *
- * If user suggests a Max IO size to use, use the smaller of the
- * user's value and the calculated value as long as the user's
- * value is larger than 0. The user's value is in pages.
- */
- sges_per_frame = ((sc->reqframesz) /
- sizeof(MPI2_SGE_SIMPLE64)) - 1;
- cpi->maxio = (sges_per_frame * sc->facts->MaxChainDepth) + 1;
- cpi->maxio *= PAGE_SIZE;
- if ((sc->max_io_pages > 0) && (sc->max_io_pages * PAGE_SIZE <
- cpi->maxio))
- cpi->maxio = sc->max_io_pages * PAGE_SIZE;
+ cpi->maxio = sc->maxio;
mpssas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
}
Index: head/sys/dev/mps/mpsvar.h
===================================================================
--- head/sys/dev/mps/mpsvar.h
+++ head/sys/dev/mps/mpsvar.h
@@ -315,6 +315,7 @@
int chain_free;
int max_chains;
int max_io_pages;
+ u_int maxio;
int chain_free_lowwater;
u_int enable_ssu;
int spinup_wait_time;
@@ -349,6 +350,7 @@
int num_reqs;
int num_prireqs;
int num_replies;
+ int num_chains;
int fqdepth; /* Free queue */
int pqdepth; /* Post queue */

File Metadata

Mime Type
text/plain
Expires
Wed, Jan 14, 8:11 AM (7 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27635573
Default Alt Text
D14261.diff (11 KB)

Event Timeline