diff options
author | xun ni - Sun Microsystems - Beijing China <Xun.Ni@Sun.COM> | 2010-06-03 10:07:17 +0800 |
---|---|---|
committer | xun ni - Sun Microsystems - Beijing China <Xun.Ni@Sun.COM> | 2010-06-03 10:07:17 +0800 |
commit | 81a0678e1c5837dd278edbcc4a617a6c976e7673 (patch) | |
tree | b3d0fea1913950eb335d8c624076ac22ae397934 | |
parent | 3492a3fe3944f9ca1cec72cc39496c7a257b5707 (diff) | |
download | illumos-gate-81a0678e1c5837dd278edbcc4a617a6c976e7673.tar.gz |
6458733 si3124 sata HBA driver has arbitrary low number of scatter-gather entries affecting performance
-rw-r--r-- | usr/src/uts/common/io/sata/adapters/si3124/si3124.c | 59 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sata/adapters/si3124/si3124var.h | 15 |
3 files changed, 53 insertions, 25 deletions
diff --git a/usr/src/uts/common/io/sata/adapters/si3124/si3124.c b/usr/src/uts/common/io/sata/adapters/si3124/si3124.c index 31e715d12e..20a61c3832 100644 --- a/usr/src/uts/common/io/sata/adapters/si3124/si3124.c +++ b/usr/src/uts/common/io/sata/adapters/si3124/si3124.c @@ -75,10 +75,13 @@ * * external SGT tables: The external SGT tables pointed to from * within si_prb_t are actually abstracted as si_sgblock_t. Each - * si_sgblock_t contains SI_MAX_SGT_TABLES_PER_PRB number of - * SGT tables linked in a chain. Currently this max value of - * SGT tables per block is hard coded as 10 which translates - * to a maximum of 31 dma cookies per single dma transfer. + * si_sgblock_t contains si_dma_sg_number number of + * SGT tables linked in a chain. Currently this default value of + * SGT tables per block is at 85 as which translates + * to a maximum of 256 dma cookies per single dma transfer. + * This value can be changed through the global var: si_dma_sg_number + * in /etc/system, the maxium is at 21844 as which translates to 65535 + * dma cookies per single dma transfer. * * * III. Driver operation @@ -342,7 +345,7 @@ static ddi_dma_attr_t buffer_dma_attr = { 1, /* dma_attr_minxfer */ 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */ 0xffffffffull, /* dma_attr_seg */ - SI_MAX_SGL_LENGTH, /* dma_attr_sgllen */ + SI_DEFAULT_SGL_LENGTH, /* dma_attr_sgllen */ 512, /* dma_attr_granular */ 0, /* dma_attr_flags */ }; @@ -422,6 +425,14 @@ static char si_log_buf[512]; uint32_t si_debug_flags = 0x0; static int is_msi_supported = 0; +/* + * The below global variables are tunable via /etc/system + * + * si_dma_sg_number + */ + +int si_dma_sg_number = SI_DEFAULT_SGT_TABLES_PER_PRB; + /* Opaque state pointer to be initialized by ddi_soft_state_init() */ static void *si_statep = NULL; @@ -1033,6 +1044,16 @@ si_register_sata_hba_tran(si_ctl_state_t *si_ctlp) sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV; sata_hba_tran->sata_tran_hba_dip = si_ctlp->sictl_devinfop; + + if (si_dma_sg_number > SI_MAX_SGT_TABLES_PER_PRB) { + si_dma_sg_number = SI_MAX_SGT_TABLES_PER_PRB; + } else if (si_dma_sg_number < SI_MIN_SGT_TABLES_PER_PRB) { + si_dma_sg_number = SI_MIN_SGT_TABLES_PER_PRB; + } + + if (si_dma_sg_number != SI_DEFAULT_SGT_TABLES_PER_PRB) { + buffer_dma_attr.dma_attr_sgllen = SGE_LENGTH(si_dma_sg_number); + } sata_hba_tran->sata_tran_hba_dma_attr = &buffer_dma_attr; sata_hba_tran->sata_tran_hba_num_cports = si_ctlp->sictl_num_ports; @@ -1961,7 +1982,8 @@ si_alloc_sgbpool(si_ctl_state_t *si_ctlp, int port) { si_port_state_t *si_portp; uint_t cookie_count; - size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t); + size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t) + * si_dma_sg_number; size_t ret_len; ddi_dma_cookie_t sgbpool_dma_cookie; @@ -2615,7 +2637,7 @@ si_deliver_satapkt( if (spkt->satapkt_cmd.satacmd_num_dma_cookies) { prb->prb_sge1.sge_addr = si_portp->siport_sgbpool_physaddr + - slot*sizeof (si_sgblock_t); + slot * sizeof (si_sgblock_t) * si_dma_sg_number; SET_SGE_LNK(prb->prb_sge1); } else { SET_SGE_TRM(prb->prb_sge1); @@ -2625,7 +2647,7 @@ si_deliver_satapkt( if (spkt->satapkt_cmd.satacmd_num_dma_cookies) { prb->prb_sge0.sge_addr = si_portp->siport_sgbpool_physaddr + - slot*sizeof (si_sgblock_t); + slot * sizeof (si_sgblock_t) * si_dma_sg_number; SET_SGE_LNK(prb->prb_sge0); } else { @@ -2635,14 +2657,15 @@ si_deliver_satapkt( /* sge1 is left empty in non-ATAPI case */ } - bzero(&si_portp->siport_sgbpool[slot], sizeof (si_sgblock_t)); + bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number], + sizeof (si_sgblock_t) * si_dma_sg_number); ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies; - ASSERT(ncookies <= SI_MAX_SGL_LENGTH); + ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number))); SIDBG1(SIDBG_COOKIES, si_ctlp, "total ncookies: %d", ncookies); if (ncookies == 0) { - sgbp = &si_portp->siport_sgbpool[slot]; + sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number]; sgtp = &sgbp->sgb_sgt[0]; sgep = &sgtp->sgt_sge[0]; @@ -2657,10 +2680,11 @@ si_deliver_satapkt( goto sgl_fill_done; } - for (i = 0, cookie_index = 0, sgbp = &si_portp->siport_sgbpool[slot]; - i < SI_MAX_SGT_TABLES_PER_PRB; i++) { + for (i = 0, cookie_index = 0, + sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number]; + i < si_dma_sg_number; i++) { - sgtp = &sgbp->sgb_sgt[i]; + sgtp = &sgbp->sgb_sgt[0] + i; /* Now fill the first 3 entries of SGT in the loop below. */ for (j = 0, sgep = &sgtp->sgt_sge[0]; @@ -2708,7 +2732,7 @@ si_deliver_satapkt( cookie_index, ncookies); sgep->sge_addr = si_portp->siport_sgbpool_physaddr + - slot * sizeof (si_sgblock_t) + + slot * sizeof (si_sgblock_t) * si_dma_sg_number + (i+1) * sizeof (si_sgt_t); SET_SGE_LNK((*sgep)); @@ -2783,8 +2807,9 @@ sgl_fill_done: "si_deliver_satpkt sgt: low, high, count link"); for (j = 0, tmpsgep = (si_sge_t *) - &si_portp->siport_sgbpool[slot]; - j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t)); + &si_portp->siport_sgbpool[slot * si_dma_sg_number]; + j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t)) + *si_dma_sg_number; j++, tmpsgep++) { ptr = (int *)(void *)tmpsgep; cmn_err(CE_WARN, "%x %x %x %x", diff --git a/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h b/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h index 97e43d859c..d77aa5ba5d 100644 --- a/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h +++ b/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h @@ -297,8 +297,8 @@ typedef struct si_prb { DDI_DMA_SYNC_FORDEV); \ \ (void) ddi_dma_sync(si_portp->siport_sgbpool_dma_handle, \ - slot * sizeof (si_sgblock_t), \ - sizeof (si_sgblock_t), \ + slot * sizeof (si_sgblock_t) * si_dma_sg_number, \ + sizeof (si_sgblock_t) * si_dma_sg_number, \ DDI_DMA_SYNC_FORDEV); \ \ ddi_put64(si_ctlp->sictl_port_acc_handle, \ diff --git a/usr/src/uts/common/sys/sata/adapters/si3124/si3124var.h b/usr/src/uts/common/sys/sata/adapters/si3124/si3124var.h index bb7d270d56..139224912e 100644 --- a/usr/src/uts/common/sys/sata/adapters/si3124/si3124var.h +++ b/usr/src/uts/common/sys/sata/adapters/si3124/si3124var.h @@ -38,17 +38,19 @@ extern "C" { #define SI_TIMEOUT (1) /* timed out */ #define SI_FAILURE (-1) /* unsuccessful return */ -#define SI_MAX_SGT_TABLES_PER_PRB 10 - +#define SI_MAX_SGT_TABLES_PER_PRB 21844 +#define SI_DEFAULT_SGT_TABLES_PER_PRB 85 +#define SI_MIN_SGT_TABLES_PER_PRB 1 /* * While the si_sge_t and si_sgt_t correspond to the actual SGE and SGT * definitions as per the datasheet, the si_sgblock_t (i.e scatter gather - * block) is a logical data structure which holds multiple SGT tables. - * The idea is to use multiple chained SGT tables per each PRB request. + * block) is a logical data structure which can hold dynamic SGEs and it + * is tunable through global variables /etc/system si3124:si_dma_sg_number. + * The idea is to use multiple tunable chained SGT tables per each PRB request. */ typedef struct si_sgblock { - si_sgt_t sgb_sgt[SI_MAX_SGT_TABLES_PER_PRB]; + si_sgt_t sgb_sgt[1]; } si_sgblock_t; /* @@ -58,7 +60,8 @@ typedef struct si_sgblock { * SGT in the chain can host all the 4 entries since it does not need to * link any more. */ -#define SI_MAX_SGL_LENGTH (3*SI_MAX_SGT_TABLES_PER_PRB)+1 +#define SGE_LENGTH(x) (3*(x)+1) +#define SI_DEFAULT_SGL_LENGTH SGE_LENGTH(SI_DEFAULT_SGT_TABLES_PER_PRB) typedef struct si_portmult_state { int sipm_num_ports; |