aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-11-12 18:04:06 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:24:04 -0500
commit35f805b52c94f8e6cb22907ef32517132a15cb96 (patch)
treeeb26ec6db8b4093d5659eb0f351b1dbc228c5359 /drivers/scsi/mpt2sas/mpt2sas_base.c
parent6cb8ef573fd4c2bd72248f492fe336133660148d (diff)
[SCSI] mpt2sas: Create a pool of chain buffer instead of dedicated per IOs
Create a pool of chain buffers, instead of dedicated per IO: This enahancment is to address memory allocation failure when asking for more than 2300 IOs per host. There is just not enough contiquious DMA physical memory to make one single allocation to hold both message frames and chain buffers when asking for more than 2300 request. In order to address this problem we will have to allocate memory for each chain buffer in a seperate individual memory allocation, placing each chain element of 128 bytes onto a pool of available chains, which can be shared amoung all request. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c87
1 files changed, 70 insertions, 17 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0e30827d44e7..c8f39f8c6fed 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -65,7 +65,6 @@
65static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; 65static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
66 66
67#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ 67#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
68#define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */
69 68
70static int max_queue_depth = -1; 69static int max_queue_depth = -1;
71module_param(max_queue_depth, int, 0); 70module_param(max_queue_depth, int, 0);
@@ -1497,6 +1496,7 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1497{ 1496{
1498 unsigned long flags; 1497 unsigned long flags;
1499 int i; 1498 int i;
1499 struct chain_tracker *chain_req, *next;
1500 1500
1501 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 1501 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1502 if (smid >= ioc->hi_priority_smid) { 1502 if (smid >= ioc->hi_priority_smid) {
@@ -1519,6 +1519,14 @@ mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1519 1519
1520 /* scsiio queue */ 1520 /* scsiio queue */
1521 i = smid - 1; 1521 i = smid - 1;
1522 if (!list_empty(&ioc->scsi_lookup[i].chain_list)) {
1523 list_for_each_entry_safe(chain_req, next,
1524 &ioc->scsi_lookup[i].chain_list, tracker_list) {
1525 list_del_init(&chain_req->tracker_list);
1526 list_add_tail(&chain_req->tracker_list,
1527 &ioc->free_chain_list);
1528 }
1529 }
1522 ioc->scsi_lookup[i].cb_idx = 0xFF; 1530 ioc->scsi_lookup[i].cb_idx = 0xFF;
1523 ioc->scsi_lookup[i].scmd = NULL; 1531 ioc->scsi_lookup[i].scmd = NULL;
1524 list_add_tail(&ioc->scsi_lookup[i].tracker_list, 1532 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
@@ -1968,6 +1976,8 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc)
1968static void 1976static void
1969_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc) 1977_base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1970{ 1978{
1979 int i;
1980
1971 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 1981 dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
1972 __func__)); 1982 __func__));
1973 1983
@@ -2032,6 +2042,20 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
2032 } 2042 }
2033 kfree(ioc->hpr_lookup); 2043 kfree(ioc->hpr_lookup);
2034 kfree(ioc->internal_lookup); 2044 kfree(ioc->internal_lookup);
2045 if (ioc->chain_lookup) {
2046 for (i = 0; i < ioc->chain_depth; i++) {
2047 if (ioc->chain_lookup[i].chain_buffer)
2048 pci_pool_free(ioc->chain_dma_pool,
2049 ioc->chain_lookup[i].chain_buffer,
2050 ioc->chain_lookup[i].chain_buffer_dma);
2051 }
2052 if (ioc->chain_dma_pool)
2053 pci_pool_destroy(ioc->chain_dma_pool);
2054 }
2055 if (ioc->chain_lookup) {
2056 free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
2057 ioc->chain_lookup = NULL;
2058 }
2035} 2059}
2036 2060
2037 2061
@@ -2053,6 +2077,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2053 u32 sz, total_sz; 2077 u32 sz, total_sz;
2054 u32 retry_sz; 2078 u32 retry_sz;
2055 u16 max_request_credit; 2079 u16 max_request_credit;
2080 int i;
2056 2081
2057 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 2082 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
2058 __func__)); 2083 __func__));
@@ -2070,14 +2095,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2070 } 2095 }
2071 2096
2072 /* command line tunables for max controller queue depth */ 2097 /* command line tunables for max controller queue depth */
2073 if (max_queue_depth != -1) { 2098 if (max_queue_depth != -1)
2074 max_request_credit = (max_queue_depth < facts->RequestCredit) 2099 max_request_credit = (max_queue_depth < facts->RequestCredit)
2075 ? max_queue_depth : facts->RequestCredit; 2100 ? max_queue_depth : facts->RequestCredit;
2076 } else { 2101 else
2077 max_request_credit = (facts->RequestCredit > 2102 max_request_credit = facts->RequestCredit;
2078 MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
2079 facts->RequestCredit;
2080 }
2081 2103
2082 ioc->hba_queue_depth = max_request_credit; 2104 ioc->hba_queue_depth = max_request_credit;
2083 ioc->hi_priority_depth = facts->HighPriorityCredit; 2105 ioc->hi_priority_depth = facts->HighPriorityCredit;
@@ -2183,7 +2205,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2183 * "frame for smid=0 2205 * "frame for smid=0
2184 */ 2206 */
2185 ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth; 2207 ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
2186 sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz); 2208 sz = ((ioc->scsiio_depth + 1) * ioc->request_sz);
2187 2209
2188 /* hi-priority queue */ 2210 /* hi-priority queue */
2189 sz += (ioc->hi_priority_depth * ioc->request_sz); 2211 sz += (ioc->hi_priority_depth * ioc->request_sz);
@@ -2224,19 +2246,11 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2224 ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth * 2246 ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
2225 ioc->request_sz); 2247 ioc->request_sz);
2226 2248
2227 ioc->chain = ioc->internal + (ioc->internal_depth *
2228 ioc->request_sz);
2229 ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth *
2230 ioc->request_sz);
2231 2249
2232 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): " 2250 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
2233 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, 2251 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
2234 ioc->request, ioc->hba_queue_depth, ioc->request_sz, 2252 ioc->request, ioc->hba_queue_depth, ioc->request_sz,
2235 (ioc->hba_queue_depth * ioc->request_sz)/1024)); 2253 (ioc->hba_queue_depth * ioc->request_sz)/1024));
2236 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
2237 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
2238 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
2239 ioc->request_sz))/1024));
2240 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n", 2254 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool: dma(0x%llx)\n",
2241 ioc->name, (unsigned long long) ioc->request_dma)); 2255 ioc->name, (unsigned long long) ioc->request_dma));
2242 total_sz += sz; 2256 total_sz += sz;
@@ -2255,6 +2269,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2255 "depth(%d)\n", ioc->name, ioc->request, 2269 "depth(%d)\n", ioc->name, ioc->request,
2256 ioc->scsiio_depth)); 2270 ioc->scsiio_depth));
2257 2271
2272 /* loop till the allocation succeeds */
2273 do {
2274 sz = ioc->chain_depth * sizeof(struct chain_tracker);
2275 ioc->chain_pages = get_order(sz);
2276 ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
2277 GFP_KERNEL, ioc->chain_pages);
2278 if (ioc->chain_lookup == NULL)
2279 ioc->chain_depth -= 100;
2280 } while (ioc->chain_lookup == NULL);
2281 ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
2282 ioc->request_sz, 16, 0);
2283 if (!ioc->chain_dma_pool) {
2284 printk(MPT2SAS_ERR_FMT "chain_dma_pool: pci_pool_create "
2285 "failed\n", ioc->name);
2286 goto out;
2287 }
2288 for (i = 0; i < ioc->chain_depth; i++) {
2289 ioc->chain_lookup[i].chain_buffer = pci_pool_alloc(
2290 ioc->chain_dma_pool , GFP_KERNEL,
2291 &ioc->chain_lookup[i].chain_buffer_dma);
2292 if (!ioc->chain_lookup[i].chain_buffer) {
2293 ioc->chain_depth = i;
2294 goto chain_done;
2295 }
2296 total_sz += ioc->request_sz;
2297 }
2298chain_done:
2299 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool depth"
2300 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
2301 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
2302 ioc->request_sz))/1024));
2303
2258 /* initialize hi-priority queue smid's */ 2304 /* initialize hi-priority queue smid's */
2259 ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, 2305 ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
2260 sizeof(struct request_tracker), GFP_KERNEL); 2306 sizeof(struct request_tracker), GFP_KERNEL);
@@ -2404,7 +2450,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2404 return 0; 2450 return 0;
2405 2451
2406 out: 2452 out:
2407 _base_release_memory_pools(ioc);
2408 return -ENOMEM; 2453 return -ENOMEM;
2409} 2454}
2410 2455
@@ -3587,6 +3632,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3587 INIT_LIST_HEAD(&ioc->free_list); 3632 INIT_LIST_HEAD(&ioc->free_list);
3588 smid = 1; 3633 smid = 1;
3589 for (i = 0; i < ioc->scsiio_depth; i++, smid++) { 3634 for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
3635 INIT_LIST_HEAD(&ioc->scsi_lookup[i].chain_list);
3590 ioc->scsi_lookup[i].cb_idx = 0xFF; 3636 ioc->scsi_lookup[i].cb_idx = 0xFF;
3591 ioc->scsi_lookup[i].smid = smid; 3637 ioc->scsi_lookup[i].smid = smid;
3592 ioc->scsi_lookup[i].scmd = NULL; 3638 ioc->scsi_lookup[i].scmd = NULL;
@@ -3613,6 +3659,13 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3613 list_add_tail(&ioc->internal_lookup[i].tracker_list, 3659 list_add_tail(&ioc->internal_lookup[i].tracker_list,
3614 &ioc->internal_free_list); 3660 &ioc->internal_free_list);
3615 } 3661 }
3662
3663 /* chain pool */
3664 INIT_LIST_HEAD(&ioc->free_chain_list);
3665 for (i = 0; i < ioc->chain_depth; i++)
3666 list_add_tail(&ioc->chain_lookup[i].tracker_list,
3667 &ioc->free_chain_list);
3668
3616 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 3669 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3617 3670
3618 /* initialize Reply Free Queue */ 3671 /* initialize Reply Free Queue */