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

be2iscsi: Fix interrupt Coalescing mechanism.

Signed-off-by: default avatarMinh Tran <minhduc.tran@emulex.com>
Signed-off-by: default avatarJohn Soni Jose <sony.john-n@emulex.com>
Signed-off-by: default avatarJayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 0598b8af
......@@ -83,9 +83,20 @@ static inline void queue_tail_inc(struct be_queue_info *q)
/*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 {
bool todo_mcc_cq;
bool todo_cq;
u32 cq_count;
struct be_queue_info q;
struct beiscsi_hba *phba;
struct be_queue_info *cq;
......
......@@ -271,6 +271,12 @@ struct be_cmd_resp_eq_create {
u16 rsvd0; /* sword */
} __packed;
struct be_set_eqd {
u32 eq_id;
u32 phase;
u32 delay_multiplier;
} __packed;
struct mgmt_chap_format {
u32 flags;
u8 intr_chap_name[256];
......@@ -622,7 +628,7 @@ struct be_cmd_req_modify_eq_delay {
u32 eq_id;
u32 phase;
u32 delay_multiplier;
} delay[8];
} delay[MAX_CPUS];
} __packed;
/******************** 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);
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *,
int num);
int beiscsi_mccq_compl(struct beiscsi_hba *phba,
uint32_t tag, struct be_mcc_wrb **wrb,
struct be_dma_mem *mbx_cmd_mem);
......
......@@ -2271,6 +2271,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget)
pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
ret = beiscsi_process_cq(pbe_eq);
pbe_eq->cq_count += ret;
if (ret < budget) {
phba = pbe_eq->phba;
blk_iopoll_complete(iop);
......@@ -3825,9 +3826,9 @@ static int hwi_init_port(struct beiscsi_hba *phba)
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
phwi_context->max_eqd = 0;
phwi_context->max_eqd = 128;
phwi_context->min_eqd = 0;
phwi_context->cur_eqd = 64;
phwi_context->cur_eqd = 0;
be_cmd_fw_initialize(&phba->ctrl);
status = beiscsi_create_eqs(phba, phwi_context);
......@@ -5282,6 +5283,57 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba)
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
* @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,
beiscsi_hw_check_task.work);
be_eqd_update(phba);
beiscsi_ue_detect(phba);
schedule_delayed_work(&phba->beiscsi_hw_check_task,
......
......@@ -72,7 +72,7 @@
#define BEISCSI_SGLIST_ELEMENTS 30
#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_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
......@@ -427,6 +427,7 @@ struct beiscsi_hba {
struct mgmt_session_info boot_sess;
struct invalidate_command_table inv_tbl[128];
struct be_aic_obj aic_obj[MAX_CPUS];
unsigned int attr_log_enable;
int (*iotask_fn)(struct iscsi_task *,
struct scatterlist *sg,
......
......@@ -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
* @phba: Device priv structure instance
......
......@@ -335,5 +335,7 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
struct wrb_handle *pwrb_handle);
void beiscsi_ue_detect(struct beiscsi_hba *phba);
int be_cmd_modify_eq_delay(struct beiscsi_hba *phba,
struct be_set_eqd *, int num);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment