[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>
This commit is contained in:
parent
23dcfa61ba
commit
338b131a32
|
@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* command line tunables for max controller queue depth */
|
/* command line tunables for max controller queue depth */
|
||||||
if (max_queue_depth != -1)
|
if (max_queue_depth != -1 && max_queue_depth != 0) {
|
||||||
max_request_credit = (max_queue_depth < facts->RequestCredit)
|
max_request_credit = min_t(u16, max_queue_depth +
|
||||||
? max_queue_depth : facts->RequestCredit;
|
ioc->hi_priority_depth + ioc->internal_depth,
|
||||||
else
|
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_request_credit = min_t(u16, facts->RequestCredit,
|
||||||
MAX_HBA_QUEUE_DEPTH);
|
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
|
/* set the scsi host can_queue depth
|
||||||
* with some internal commands that could be outstanding
|
* 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: "
|
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "
|
||||||
"can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));
|
"can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));
|
||||||
|
|
||||||
|
|
Reference in New Issue