diff options
author | sreekanth.reddy@lsi.com <sreekanth.reddy@lsi.com> | 2012-07-17 06:27:05 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-08-22 01:38:49 -0400 |
commit | 338b131a3269881c7431234855c93c219b0979b6 (patch) | |
tree | 741f394a7159c15ed73281ce563d5d8e3d176f9a /drivers/scsi | |
parent | 23dcfa61bac244e1200ff9ad19c6e9144dcb6bb5 (diff) |
[SCSI] mpt2sas: Fix for Driver oops, when loading driver with max_queue_depth command line option to a very small value
If the specified max_queue_depth setting is less than the
expected number of internal commands, then driver will calculate
the queue depth size to a negitive number. This negitive number
is actually a very large number because variable is unsigned
16bit integer. So, the driver will ask for a very large amount of
memory for message frames and resulting into oops as memory
allocation routines will not able to handle such a large request.
So, in order to limit this kind of oops, The driver need to set
the max_queue_depth to a scsi mid layer's can_queue value. Then
the overall message frames required for IO is minimum of either
(max_queue_depth plus internal commands) or the IOC global
credits.
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@lsi.com>
Cc: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe7755..b25757d1e91b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2424 | } | 2424 | } |
2425 | 2425 | ||
2426 | /* command line tunables for max controller queue depth */ | 2426 | /* command line tunables for max controller queue depth */ |
2427 | if (max_queue_depth != -1) | 2427 | if (max_queue_depth != -1 && max_queue_depth != 0) { |
2428 | max_request_credit = (max_queue_depth < facts->RequestCredit) | 2428 | max_request_credit = min_t(u16, max_queue_depth + |
2429 | ? max_queue_depth : facts->RequestCredit; | 2429 | ioc->hi_priority_depth + ioc->internal_depth, |
2430 | else | 2430 | facts->RequestCredit); |
2431 | if (max_request_credit > MAX_HBA_QUEUE_DEPTH) | ||
2432 | max_request_credit = MAX_HBA_QUEUE_DEPTH; | ||
2433 | } else | ||
2431 | max_request_credit = min_t(u16, facts->RequestCredit, | 2434 | max_request_credit = min_t(u16, facts->RequestCredit, |
2432 | MAX_HBA_QUEUE_DEPTH); | 2435 | MAX_HBA_QUEUE_DEPTH); |
2433 | 2436 | ||
@@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2502 | /* set the scsi host can_queue depth | 2505 | /* set the scsi host can_queue depth |
2503 | * with some internal commands that could be outstanding | 2506 | * with some internal commands that could be outstanding |
2504 | */ | 2507 | */ |
2505 | ioc->shost->can_queue = ioc->scsiio_depth - (2); | 2508 | ioc->shost->can_queue = ioc->scsiio_depth; |
2506 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " | 2509 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " |
2507 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); | 2510 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); |
2508 | 2511 | ||