diff options
| author | sreekanth.reddy@lsi.com <sreekanth.reddy@lsi.com> | 2012-07-17 15:57:05 +0530 | 
|---|---|---|
| committer | James Bottomley <JBottomley@Parallels.com> | 2012-08-22 09:38:49 +0400 | 
| commit | 338b131a3269881c7431234855c93c219b0979b6 (patch) | |
| tree | 741f394a7159c15ed73281ce563d5d8e3d176f9a | |
| parent | 23dcfa61bac244e1200ff9ad19c6e9144dcb6bb5 (diff) | |
| download | olio-linux-3.10-338b131a3269881c7431234855c93c219b0979b6.tar.xz olio-linux-3.10-338b131a3269881c7431234855c93c219b0979b6.zip  | |
[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>
| -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 9d46fcbe775..b25757d1e91 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)  	}  	/* command line tunables  for max controller queue depth */ -	if (max_queue_depth != -1) -		max_request_credit = (max_queue_depth < facts->RequestCredit) -		    ? max_queue_depth : facts->RequestCredit; -	else +	if (max_queue_depth != -1 && max_queue_depth != 0) { +		max_request_credit = min_t(u16, max_queue_depth + +			ioc->hi_priority_depth + ioc->internal_depth, +			facts->RequestCredit); +		if (max_request_credit > MAX_HBA_QUEUE_DEPTH) +			max_request_credit =  MAX_HBA_QUEUE_DEPTH; +	} else  		max_request_credit = min_t(u16, facts->RequestCredit,  		    MAX_HBA_QUEUE_DEPTH); @@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc,  int sleep_flag)  	/* set the scsi host can_queue depth  	 * with some internal commands that could be outstanding  	 */ -	ioc->shost->can_queue = ioc->scsiio_depth - (2); +	ioc->shost->can_queue = ioc->scsiio_depth;  	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "  	    "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));  |