Loading drivers/scsi/be2iscsi/be.h +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/scsi/be2iscsi/be_cmds.h +9 −1 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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 *******************/ Loading Loading @@ -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); Loading drivers/scsi/be2iscsi/be_main.c +56 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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 Loading @@ -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, Loading drivers/scsi/be2iscsi/be_main.h +3 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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, Loading drivers/scsi/be2iscsi/be_mgmt.c +37 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
drivers/scsi/be2iscsi/be.h +11 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/scsi/be2iscsi/be_cmds.h +9 −1 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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 *******************/ Loading Loading @@ -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); Loading
drivers/scsi/be2iscsi/be_main.c +56 −2 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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); Loading Loading @@ -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 Loading @@ -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, Loading
drivers/scsi/be2iscsi/be_main.h +3 −2 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -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, Loading
drivers/scsi/be2iscsi/be_mgmt.c +37 −0 Original line number Diff line number Diff line Loading @@ -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 Loading