mirror of
https://github.com/torvalds/linux
synced 2024-10-20 10:19:54 +00:00
[SCSI] qla4xxx: Throttle active IOCBs to firmware limits
Problem: QLA4xxx firmware may assert if given more IOCBs than it can handle. Solution: The driver was updated to throttle the number of active IOCBs based on the total number of IOCB buffers received from get_firmware_status mbx_sts[2]. Signed-off-by: Karen Higgins <karen.higgins@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
ff4108dce9
commit
5b1c1bff07
|
@ -136,6 +136,7 @@
|
||||||
#define RESPONSE_QUEUE_DEPTH 64
|
#define RESPONSE_QUEUE_DEPTH 64
|
||||||
#define QUEUE_SIZE 64
|
#define QUEUE_SIZE 64
|
||||||
#define DMA_BUFFER_SIZE 512
|
#define DMA_BUFFER_SIZE 512
|
||||||
|
#define IOCB_HIWAT_CUSHION 4
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Misc
|
* Misc
|
||||||
|
@ -540,6 +541,7 @@ struct scsi_qla_host {
|
||||||
uint32_t tot_ddbs;
|
uint32_t tot_ddbs;
|
||||||
|
|
||||||
uint16_t iocb_cnt;
|
uint16_t iocb_cnt;
|
||||||
|
uint16_t iocb_hiwat;
|
||||||
|
|
||||||
/* SRB cache. */
|
/* SRB cache. */
|
||||||
#define SRB_MIN_REQ 128
|
#define SRB_MIN_REQ 128
|
||||||
|
|
|
@ -316,7 +316,7 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb)
|
||||||
goto queuing_error;
|
goto queuing_error;
|
||||||
|
|
||||||
/* total iocbs active */
|
/* total iocbs active */
|
||||||
if ((ha->iocb_cnt + req_cnt) >= REQUEST_QUEUE_DEPTH)
|
if ((ha->iocb_cnt + req_cnt) >= ha->iocb_hiwat)
|
||||||
goto queuing_error;
|
goto queuing_error;
|
||||||
|
|
||||||
/* Build command packet */
|
/* Build command packet */
|
||||||
|
|
|
@ -697,8 +697,24 @@ int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
|
||||||
return QLA_ERROR;
|
return QLA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ql4_printk(KERN_INFO, ha, "%ld firmware IOCBs available (%d).\n",
|
/* High-water mark of IOCBs */
|
||||||
ha->host_no, mbox_sts[2]);
|
ha->iocb_hiwat = mbox_sts[2];
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||||
|
"%s: firmware IOCBs available = %d\n", __func__,
|
||||||
|
ha->iocb_hiwat));
|
||||||
|
|
||||||
|
if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
|
||||||
|
ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
|
||||||
|
|
||||||
|
/* Ideally, we should not enter this code, as the # of firmware
|
||||||
|
* IOCBs is hard-coded in the firmware. We set a default
|
||||||
|
* iocb_hiwat here just in case */
|
||||||
|
if (ha->iocb_hiwat == 0) {
|
||||||
|
ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4;
|
||||||
|
DEBUG2(ql4_printk(KERN_WARNING, ha,
|
||||||
|
"%s: Setting IOCB's to = %d\n", __func__,
|
||||||
|
ha->iocb_hiwat));
|
||||||
|
}
|
||||||
|
|
||||||
return QLA_SUCCESS;
|
return QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue