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

Commit 73af08e1 authored by Jayamohan Kallickal's avatar Jayamohan Kallickal Committed by Christoph Hellwig
Browse files

be2iscsi: Fix interrupt Coalescing mechanism.

parent 0598b8af
Loading
Loading
Loading
Loading
+11 −0
Original line number Original line Diff line number Diff line
@@ -83,9 +83,20 @@ static inline void queue_tail_inc(struct be_queue_info *q)


/*ISCSI */
/*ISCSI */


struct be_aic_obj {		/* Adaptive interrupt coalescing (AIC) info */
	bool enable;
	u32 min_eqd;		/* in usecs */
	u32 max_eqd;		/* in usecs */
	u32 prev_eqd;		/* in usecs */
	u32 et_eqd;		/* configured val when aic is off */
	ulong jiffs;
	u64 eq_prev;		/* Used to calculate eqe */
};

struct be_eq_obj {
struct be_eq_obj {
	bool todo_mcc_cq;
	bool todo_mcc_cq;
	bool todo_cq;
	bool todo_cq;
	u32 cq_count;
	struct be_queue_info q;
	struct be_queue_info q;
	struct beiscsi_hba *phba;
	struct beiscsi_hba *phba;
	struct be_queue_info *cq;
	struct be_queue_info *cq;
+9 −1
Original line number Original line Diff line number Diff line
@@ -271,6 +271,12 @@ struct be_cmd_resp_eq_create {
	u16 rsvd0;		/* sword */
	u16 rsvd0;		/* sword */
} __packed;
} __packed;


struct be_set_eqd {
	u32 eq_id;
	u32 phase;
	u32 delay_multiplier;
} __packed;

struct mgmt_chap_format {
struct mgmt_chap_format {
	u32 flags;
	u32 flags;
	u8  intr_chap_name[256];
	u8  intr_chap_name[256];
@@ -622,7 +628,7 @@ struct be_cmd_req_modify_eq_delay {
		u32 eq_id;
		u32 eq_id;
		u32 phase;
		u32 phase;
		u32 delay_multiplier;
		u32 delay_multiplier;
	} delay[8];
	} delay[MAX_CPUS];
} __packed;
} __packed;


/******************** Get MAC ADDR *******************/
/******************** Get MAC ADDR *******************/
@@ -708,6 +714,8 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);


void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);


int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
			    int num);
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
			uint32_t tag, struct be_mcc_wrb **wrb,
			uint32_t tag, struct be_mcc_wrb **wrb,
			struct be_dma_mem *mbx_cmd_mem);
			struct be_dma_mem *mbx_cmd_mem);
+56 −2
Original line number Original line Diff line number Diff line
@@ -2271,6 +2271,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)


	pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
	pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
	ret = beiscsi_process_cq(pbe_eq);
	ret = beiscsi_process_cq(pbe_eq);
	pbe_eq->cq_count += ret;
	if (ret < budget) {
	if (ret < budget) {
		phba = pbe_eq->phba;
		phba = pbe_eq->phba;
		blk_iopoll_complete(iop);
		blk_iopoll_complete(iop);
@@ -3825,9 +3826,9 @@ static int hwi_init_port(struct beiscsi_hba *phba)


	phwi_ctrlr = phba->phwi_ctrlr;
	phwi_ctrlr = phba->phwi_ctrlr;
	phwi_context = phwi_ctrlr->phwi_ctxt;
	phwi_context = phwi_ctrlr->phwi_ctxt;
	phwi_context->max_eqd = 0;
	phwi_context->max_eqd = 128;
	phwi_context->min_eqd = 0;
	phwi_context->min_eqd = 0;
	phwi_context->cur_eqd = 64;
	phwi_context->cur_eqd = 0;
	be_cmd_fw_initialize(&phba->ctrl);
	be_cmd_fw_initialize(&phba->ctrl);


	status = beiscsi_create_eqs(phba, phwi_context);
	status = beiscsi_create_eqs(phba, phwi_context);
@@ -5282,6 +5283,57 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
	return;
	return;
}
}


static void be_eqd_update(struct beiscsi_hba *phba)
{
	struct be_set_eqd set_eqd[MAX_CPUS];
	struct be_aic_obj *aic;
	struct be_eq_obj *pbe_eq;
	struct hwi_controller *phwi_ctrlr;
	struct hwi_context_memory *phwi_context;
	int eqd, i, num = 0;
	ulong now;
	u32 pps, delta;
	unsigned int tag;

	phwi_ctrlr = phba->phwi_ctrlr;
	phwi_context = phwi_ctrlr->phwi_ctxt;

	for (i = 0; i <= phba->num_cpus; i++) {
		aic = &phba->aic_obj[i];
		pbe_eq = &phwi_context->be_eq[i];
		now = jiffies;
		if (!aic->jiffs || time_before(now, aic->jiffs) ||
		    pbe_eq->cq_count < aic->eq_prev) {
			aic->jiffs = now;
			aic->eq_prev = pbe_eq->cq_count;
			continue;
		}
		delta = jiffies_to_msecs(now - aic->jiffs);
		pps = (((u32)(pbe_eq->cq_count - aic->eq_prev) * 1000) / delta);
		eqd = (pps / 1500) << 2;

		if (eqd < 8)
			eqd = 0;
		eqd = min_t(u32, eqd, phwi_context->max_eqd);
		eqd = max_t(u32, eqd, phwi_context->min_eqd);

		aic->jiffs = now;
		aic->eq_prev = pbe_eq->cq_count;

		if (eqd != aic->prev_eqd) {
			set_eqd[num].delay_multiplier = (eqd * 65)/100;
			set_eqd[num].eq_id = pbe_eq->q.id;
			aic->prev_eqd = eqd;
			num++;
		}
	}
	if (num) {
		tag = be_cmd_modify_eq_delay(phba, set_eqd, num);
		if (tag)
			beiscsi_mccq_compl(phba, tag, NULL, NULL);
	}
}

/*
/*
 * beiscsi_hw_health_check()- Check adapter health
 * beiscsi_hw_health_check()- Check adapter health
 * @work: work item to check HW health
 * @work: work item to check HW health
@@ -5295,6 +5347,8 @@ beiscsi_hw_health_check(struct work_struct *work)
		container_of(work, struct beiscsi_hba,
		container_of(work, struct beiscsi_hba,
			     beiscsi_hw_check_task.work);
			     beiscsi_hw_check_task.work);


	be_eqd_update(phba);

	beiscsi_ue_detect(phba);
	beiscsi_ue_detect(phba);


	schedule_delayed_work(&phba->beiscsi_hw_check_task,
	schedule_delayed_work(&phba->beiscsi_hw_check_task,
+3 −2
Original line number Original line Diff line number Diff line
@@ -72,7 +72,7 @@
#define BEISCSI_SGLIST_ELEMENTS	30
#define BEISCSI_SGLIST_ELEMENTS	30


#define BEISCSI_CMD_PER_LUN	128 /* scsi_host->cmd_per_lun */
#define BEISCSI_CMD_PER_LUN	128 /* scsi_host->cmd_per_lun */
#define BEISCSI_MAX_SECTORS	2048	/* scsi_host->max_sectors */
#define BEISCSI_MAX_SECTORS	1024 /* scsi_host->max_sectors */
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */
#define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */


#define BEISCSI_MAX_CMD_LEN	16	/* scsi_host->max_cmd_len */
#define BEISCSI_MAX_CMD_LEN	16	/* scsi_host->max_cmd_len */
@@ -427,6 +427,7 @@ struct beiscsi_hba {
	struct mgmt_session_info boot_sess;
	struct mgmt_session_info boot_sess;
	struct invalidate_command_table inv_tbl[128];
	struct invalidate_command_table inv_tbl[128];


	struct be_aic_obj aic_obj[MAX_CPUS];
	unsigned int attr_log_enable;
	unsigned int attr_log_enable;
	int (*iotask_fn)(struct iscsi_task *,
	int (*iotask_fn)(struct iscsi_task *,
			struct scatterlist *sg,
			struct scatterlist *sg,
+37 −0
Original line number Original line Diff line number Diff line
@@ -155,6 +155,43 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba)
	}
	}
}
}


int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
		 struct be_set_eqd *set_eqd, int num)
{
	struct be_ctrl_info *ctrl = &phba->ctrl;
	struct be_mcc_wrb *wrb;
	struct be_cmd_req_modify_eq_delay *req;
	unsigned int tag = 0;
	int i;

	spin_lock(&ctrl->mbox_lock);
	tag = alloc_mcc_tag(phba);
	if (!tag) {
		spin_unlock(&ctrl->mbox_lock);
		return tag;
	}

	wrb = wrb_from_mccq(phba);
	req = embedded_payload(wrb);

	wrb->tag0 |= tag;
	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
		OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req));

	req->num_eq = cpu_to_le32(num);
	for (i = 0; i < num; i++) {
		req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id);
		req->delay[i].phase = 0;
		req->delay[i].delay_multiplier =
				cpu_to_le32(set_eqd[i].delay_multiplier);
	}

	be_mcc_notify(phba);
	spin_unlock(&ctrl->mbox_lock);
	return tag;
}

/**
/**
 * mgmt_reopen_session()- Reopen a session based on reopen_type
 * mgmt_reopen_session()- Reopen a session based on reopen_type
 * @phba: Device priv structure instance
 * @phba: Device priv structure instance
Loading