Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1e3635a authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Add boundary checks for exchanges to be offloaded



Max boundary for exchange off load is 32k exchanges. If a system
is unable to allocate large memory buffer to support this feature,
then driver will reduce the number of exchanges down to a value
system can support.

Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 3407fc37
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -288,6 +288,8 @@ struct name_list_extended {
#define ATIO_ENTRY_CNT_24XX		4096	/* Number of ATIO entries. */
#define RESPONSE_ENTRY_CNT_FX00		256     /* Number of response entries.*/
#define FW_DEF_EXCHANGES_CNT 2048
#define FW_MAX_EXCHANGES_CNT (32 * 1024)
#define REDUCE_EXCHANGES_CNT  (8 * 1024)

struct req_que;
struct qla_tgt_sess;
@@ -3506,6 +3508,7 @@ struct qla_hw_data {
		uint32_t	using_lr_setting:1;
	} flags;

	uint16_t max_exchg;
	uint16_t long_range_distance;	/* 32G & above */
#define LR_DISTANCE_5K  1
#define LR_DISTANCE_10K 0
+30 −9
Original line number Diff line number Diff line
@@ -2789,6 +2789,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
	ha->init_cb_size = sizeof(init_cb_t);
	ha->link_data_rate = PORT_SPEED_UNKNOWN;
	ha->optrom_size = OPTROM_SIZE_2300;
	ha->max_exchg = FW_MAX_EXCHANGES_CNT;

	/* Assign ISP specific operations. */
	if (IS_QLA2100(ha)) {
@@ -4230,6 +4231,9 @@ qla2x00_number_of_exch(scsi_qla_host_t *vha, u32 *ret_cnt, u16 max_cnt)
	u32 temp;
	*ret_cnt = FW_DEF_EXCHANGES_CNT;

	if (max_cnt > vha->hw->max_exchg)
		max_cnt = vha->hw->max_exchg;

	if (qla_ini_mode_enabled(vha)) {
		if (ql2xiniexchg > max_cnt)
			ql2xiniexchg = max_cnt;
@@ -4260,7 +4264,7 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
{
	int rval;
	u16	size, max_cnt;
	u32 temp;
	u32 actual_cnt, totsz;
	struct qla_hw_data *ha = vha->hw;

	if (!ha->flags.exchoffld_enabled)
@@ -4277,16 +4281,19 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
		return rval;
	}

	qla2x00_number_of_exch(vha, &temp, max_cnt);
	temp *= size;
	qla2x00_number_of_exch(vha, &actual_cnt, max_cnt);
	ql_log(ql_log_info, vha, 0xd014,
	    "Actual exchange offload count: %d.\n", actual_cnt);

	if (temp != ha->exchoffld_size) {
	totsz = actual_cnt * size;

	if (totsz != ha->exchoffld_size) {
		qla2x00_free_exchoffld_buffer(ha);
		ha->exchoffld_size = temp;
		ha->exchoffld_size = totsz;

		ql_log(ql_log_info, vha, 0xd016,
		    "Exchange offload: max_count=%d, buffers=0x%x, total=%d.\n",
		    max_cnt, size, temp);
		    "Exchange offload: max_count=%d, actual count=%d entry sz=0x%x, total sz=0x%x\n",
		    max_cnt, actual_cnt, size, totsz);

		ql_log(ql_log_info, vha, 0xd017,
		    "Exchange Buffers requested size = 0x%x\n",
@@ -4297,7 +4304,21 @@ qla2x00_set_exchoffld_buffer(scsi_qla_host_t *vha)
			ha->exchoffld_size, &ha->exchoffld_buf_dma, GFP_KERNEL);
		if (!ha->exchoffld_buf) {
			ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
			"Failed to allocate memory for exchoffld_buf_dma.\n");
			"Failed to allocate memory for Exchange Offload.\n");

			if (ha->max_exchg >
			    (FW_DEF_EXCHANGES_CNT + REDUCE_EXCHANGES_CNT)) {
				ha->max_exchg -= REDUCE_EXCHANGES_CNT;
			} else if (ha->max_exchg >
			    (FW_DEF_EXCHANGES_CNT + 512)) {
				ha->max_exchg -= 512;
			} else {
				ha->flags.exchoffld_enabled = 0;
				ql_log_pci(ql_log_fatal, ha->pdev, 0xd013,
				    "Disabling Exchange offload due to lack of memory\n");
			}
			ha->exchoffld_size = 0;

			return -ENOMEM;
		}
	}