mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-19 03:09:59 +00:00
be2iscsi: Fix interrupt Coalescing mechanism.
Signed-off-by: Minh Tran <minhduc.tran@emulex.com> Signed-off-by: John Soni Jose <sony.john-n@emulex.com> Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
0598b8afd6
commit
73af08e11c
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -71,8 +71,8 @@
|
|||||||
|
|
||||||
#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,
|
||||||
|
@ -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
|
||||||
|
@ -335,5 +335,7 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params,
|
|||||||
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
|
void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params,
|
||||||
struct wrb_handle *pwrb_handle);
|
struct wrb_handle *pwrb_handle);
|
||||||
void beiscsi_ue_detect(struct beiscsi_hba *phba);
|
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
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user