diff options
| -rw-r--r-- | drivers/scsi/be2iscsi/be.h | 11 | ||||
| -rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 10 | ||||
| -rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 58 | ||||
| -rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 5 | ||||
| -rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 37 | ||||
| -rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 2 |
6 files changed, 118 insertions, 5 deletions
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 1bfb0bd01198..860f527d8f26 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h | |||
| @@ -83,9 +83,20 @@ static inline void queue_tail_inc(struct be_queue_info *q) | |||
| 83 | 83 | ||
| 84 | /*ISCSI */ | 84 | /*ISCSI */ |
| 85 | 85 | ||
| 86 | struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */ | ||
| 87 | bool enable; | ||
| 88 | u32 min_eqd; /* in usecs */ | ||
| 89 | u32 max_eqd; /* in usecs */ | ||
| 90 | u32 prev_eqd; /* in usecs */ | ||
| 91 | u32 et_eqd; /* configured val when aic is off */ | ||
| 92 | ulong jiffs; | ||
| 93 | u64 eq_prev; /* Used to calculate eqe */ | ||
| 94 | }; | ||
| 95 | |||
| 86 | struct be_eq_obj { | 96 | struct be_eq_obj { |
| 87 | bool todo_mcc_cq; | 97 | bool todo_mcc_cq; |
| 88 | bool todo_cq; | 98 | bool todo_cq; |
| 99 | u32 cq_count; | ||
| 89 | struct be_queue_info q; | 100 | struct be_queue_info q; |
| 90 | struct beiscsi_hba *phba; | 101 | struct beiscsi_hba *phba; |
| 91 | struct be_queue_info *cq; | 102 | struct be_queue_info *cq; |
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 7cf7f99ee442..cd4410f934c7 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
| @@ -271,6 +271,12 @@ struct be_cmd_resp_eq_create { | |||
| 271 | u16 rsvd0; /* sword */ | 271 | u16 rsvd0; /* sword */ |
| 272 | } __packed; | 272 | } __packed; |
| 273 | 273 | ||
| 274 | struct be_set_eqd { | ||
| 275 | u32 eq_id; | ||
| 276 | u32 phase; | ||
| 277 | u32 delay_multiplier; | ||
| 278 | } __packed; | ||
| 279 | |||
| 274 | struct mgmt_chap_format { | 280 | struct mgmt_chap_format { |
| 275 | u32 flags; | 281 | u32 flags; |
| 276 | u8 intr_chap_name[256]; | 282 | u8 intr_chap_name[256]; |
| @@ -622,7 +628,7 @@ struct be_cmd_req_modify_eq_delay { | |||
| 622 | u32 eq_id; | 628 | u32 eq_id; |
| 623 | u32 phase; | 629 | u32 phase; |
| 624 | u32 delay_multiplier; | 630 | u32 delay_multiplier; |
| 625 | } delay[8]; | 631 | } delay[MAX_CPUS]; |
| 626 | } __packed; | 632 | } __packed; |
| 627 | 633 | ||
| 628 | /******************** Get MAC ADDR *******************/ | 634 | /******************** Get MAC ADDR *******************/ |
| @@ -708,6 +714,8 @@ unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba); | |||
| 708 | 714 | ||
| 709 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); | 715 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); |
| 710 | 716 | ||
| 717 | int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, | ||
| 718 | int num); | ||
| 711 | int beiscsi_mccq_compl(struct beiscsi_hba *phba, | 719 | int beiscsi_mccq_compl(struct beiscsi_hba *phba, |
| 712 | uint32_t tag, struct be_mcc_wrb **wrb, | 720 | uint32_t tag, struct be_mcc_wrb **wrb, |
| 713 | struct be_dma_mem *mbx_cmd_mem); | 721 | struct be_dma_mem *mbx_cmd_mem); |
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index a73af296b29d..e9f01a5f360b 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
| @@ -2271,6 +2271,7 @@ static int be_iopoll(struct blk_iopoll *iop, int budget) | |||
| 2271 | 2271 | ||
| 2272 | pbe_eq = container_of(iop, struct be_eq_obj, iopoll); | 2272 | pbe_eq = container_of(iop, struct be_eq_obj, iopoll); |
| 2273 | ret = beiscsi_process_cq(pbe_eq); | 2273 | ret = beiscsi_process_cq(pbe_eq); |
| 2274 | pbe_eq->cq_count += ret; | ||
| 2274 | if (ret < budget) { | 2275 | if (ret < budget) { |
| 2275 | phba = pbe_eq->phba; | 2276 | phba = pbe_eq->phba; |
| 2276 | blk_iopoll_complete(iop); | 2277 | blk_iopoll_complete(iop); |
| @@ -3825,9 +3826,9 @@ static int hwi_init_port(struct beiscsi_hba *phba) | |||
| 3825 | 3826 | ||
| 3826 | phwi_ctrlr = phba->phwi_ctrlr; | 3827 | phwi_ctrlr = phba->phwi_ctrlr; |
| 3827 | phwi_context = phwi_ctrlr->phwi_ctxt; | 3828 | phwi_context = phwi_ctrlr->phwi_ctxt; |
| 3828 | phwi_context->max_eqd = 0; | 3829 | phwi_context->max_eqd = 128; |
| 3829 | phwi_context->min_eqd = 0; | 3830 | phwi_context->min_eqd = 0; |
| 3830 | phwi_context->cur_eqd = 64; | 3831 | phwi_context->cur_eqd = 0; |
| 3831 | be_cmd_fw_initialize(&phba->ctrl); | 3832 | be_cmd_fw_initialize(&phba->ctrl); |
| 3832 | 3833 | ||
| 3833 | status = beiscsi_create_eqs(phba, phwi_context); | 3834 | status = beiscsi_create_eqs(phba, phwi_context); |
| @@ -5282,6 +5283,57 @@ static void beiscsi_msix_enable(struct beiscsi_hba *phba) | |||
| 5282 | return; | 5283 | return; |
| 5283 | } | 5284 | } |
| 5284 | 5285 | ||
| 5286 | static void be_eqd_update(struct beiscsi_hba *phba) | ||
| 5287 | { | ||
| 5288 | struct be_set_eqd set_eqd[MAX_CPUS]; | ||
| 5289 | struct be_aic_obj *aic; | ||
| 5290 | struct be_eq_obj *pbe_eq; | ||
| 5291 | struct hwi_controller *phwi_ctrlr; | ||
| 5292 | struct hwi_context_memory *phwi_context; | ||
| 5293 | int eqd, i, num = 0; | ||
| 5294 | ulong now; | ||
| 5295 | u32 pps, delta; | ||
| 5296 | unsigned int tag; | ||
| 5297 | |||
| 5298 | phwi_ctrlr = phba->phwi_ctrlr; | ||
| 5299 | phwi_context = phwi_ctrlr->phwi_ctxt; | ||
| 5300 | |||
| 5301 | for (i = 0; i <= phba->num_cpus; i++) { | ||
| 5302 | aic = &phba->aic_obj[i]; | ||
| 5303 | pbe_eq = &phwi_context->be_eq[i]; | ||
| 5304 | now = jiffies; | ||
| 5305 | if (!aic->jiffs || time_before(now, aic->jiffs) || | ||
| 5306 | pbe_eq->cq_count < aic->eq_prev) { | ||
| 5307 | aic->jiffs = now; | ||
| 5308 | aic->eq_prev = pbe_eq->cq_count; | ||
| 5309 | continue; | ||
| 5310 | } | ||
| 5311 | delta = jiffies_to_msecs(now - aic->jiffs); | ||
| 5312 | pps = (((u32)(pbe_eq->cq_count - aic->eq_prev) * 1000) / delta); | ||
| 5313 | eqd = (pps / 1500) << 2; | ||
| 5314 | |||
| 5315 | if (eqd < 8) | ||
| 5316 | eqd = 0; | ||
| 5317 | eqd = min_t(u32, eqd, phwi_context->max_eqd); | ||
| 5318 | eqd = max_t(u32, eqd, phwi_context->min_eqd); | ||
| 5319 | |||
| 5320 | aic->jiffs = now; | ||
| 5321 | aic->eq_prev = pbe_eq->cq_count; | ||
| 5322 | |||
| 5323 | if (eqd != aic->prev_eqd) { | ||
| 5324 | set_eqd[num].delay_multiplier = (eqd * 65)/100; | ||
| 5325 | set_eqd[num].eq_id = pbe_eq->q.id; | ||
| 5326 | aic->prev_eqd = eqd; | ||
| 5327 | num++; | ||
| 5328 | } | ||
| 5329 | } | ||
| 5330 | if (num) { | ||
| 5331 | tag = be_cmd_modify_eq_delay(phba, set_eqd, num); | ||
| 5332 | if (tag) | ||
| 5333 | beiscsi_mccq_compl(phba, tag, NULL, NULL); | ||
| 5334 | } | ||
| 5335 | } | ||
| 5336 | |||
| 5285 | /* | 5337 | /* |
| 5286 | * beiscsi_hw_health_check()- Check adapter health | 5338 | * beiscsi_hw_health_check()- Check adapter health |
| 5287 | * @work: work item to check HW health | 5339 | * @work: work item to check HW health |
| @@ -5295,6 +5347,8 @@ beiscsi_hw_health_check(struct work_struct *work) | |||
| 5295 | container_of(work, struct beiscsi_hba, | 5347 | container_of(work, struct beiscsi_hba, |
| 5296 | beiscsi_hw_check_task.work); | 5348 | beiscsi_hw_check_task.work); |
| 5297 | 5349 | ||
| 5350 | be_eqd_update(phba); | ||
| 5351 | |||
| 5298 | beiscsi_ue_detect(phba); | 5352 | beiscsi_ue_detect(phba); |
| 5299 | 5353 | ||
| 5300 | schedule_delayed_work(&phba->beiscsi_hw_check_task, | 5354 | schedule_delayed_work(&phba->beiscsi_hw_check_task, |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index 9380b55bdeaf..dc56ea91facb 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
| @@ -71,8 +71,8 @@ | |||
| 71 | 71 | ||
| 72 | #define BEISCSI_SGLIST_ELEMENTS 30 | 72 | #define BEISCSI_SGLIST_ELEMENTS 30 |
| 73 | 73 | ||
| 74 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ | 74 | #define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */ |
| 75 | #define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */ | 75 | #define BEISCSI_MAX_SECTORS 1024 /* scsi_host->max_sectors */ |
| 76 | #define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */ | 76 | #define BEISCSI_TEMPLATE_HDR_PER_CXN_SIZE 128 /* Template size per cxn */ |
| 77 | 77 | ||
| 78 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ | 78 | #define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */ |
| @@ -427,6 +427,7 @@ struct beiscsi_hba { | |||
| 427 | struct mgmt_session_info boot_sess; | 427 | struct mgmt_session_info boot_sess; |
| 428 | struct invalidate_command_table inv_tbl[128]; | 428 | struct invalidate_command_table inv_tbl[128]; |
| 429 | 429 | ||
| 430 | struct be_aic_obj aic_obj[MAX_CPUS]; | ||
| 430 | unsigned int attr_log_enable; | 431 | unsigned int attr_log_enable; |
| 431 | int (*iotask_fn)(struct iscsi_task *, | 432 | int (*iotask_fn)(struct iscsi_task *, |
| 432 | struct scatterlist *sg, | 433 | struct scatterlist *sg, |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 712911fba075..52a36fba1e2b 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
| @@ -155,6 +155,43 @@ void beiscsi_ue_detect(struct beiscsi_hba *phba) | |||
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, | ||
| 159 | struct be_set_eqd *set_eqd, int num) | ||
| 160 | { | ||
| 161 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
| 162 | struct be_mcc_wrb *wrb; | ||
| 163 | struct be_cmd_req_modify_eq_delay *req; | ||
| 164 | unsigned int tag = 0; | ||
| 165 | int i; | ||
| 166 | |||
| 167 | spin_lock(&ctrl->mbox_lock); | ||
| 168 | tag = alloc_mcc_tag(phba); | ||
| 169 | if (!tag) { | ||
| 170 | spin_unlock(&ctrl->mbox_lock); | ||
| 171 | return tag; | ||
| 172 | } | ||
| 173 | |||
| 174 | wrb = wrb_from_mccq(phba); | ||
| 175 | req = embedded_payload(wrb); | ||
| 176 | |||
| 177 | wrb->tag0 |= tag; | ||
| 178 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
| 179 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
| 180 | OPCODE_COMMON_MODIFY_EQ_DELAY, sizeof(*req)); | ||
| 181 | |||
| 182 | req->num_eq = cpu_to_le32(num); | ||
| 183 | for (i = 0; i < num; i++) { | ||
| 184 | req->delay[i].eq_id = cpu_to_le32(set_eqd[i].eq_id); | ||
| 185 | req->delay[i].phase = 0; | ||
| 186 | req->delay[i].delay_multiplier = | ||
| 187 | cpu_to_le32(set_eqd[i].delay_multiplier); | ||
| 188 | } | ||
| 189 | |||
| 190 | be_mcc_notify(phba); | ||
| 191 | spin_unlock(&ctrl->mbox_lock); | ||
| 192 | return tag; | ||
| 193 | } | ||
| 194 | |||
| 158 | /** | 195 | /** |
| 159 | * mgmt_reopen_session()- Reopen a session based on reopen_type | 196 | * mgmt_reopen_session()- Reopen a session based on reopen_type |
| 160 | * @phba: Device priv structure instance | 197 | * @phba: Device priv structure instance |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 01b8c97284c0..24a8fc577477 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h | |||
| @@ -335,5 +335,7 @@ void beiscsi_offload_cxn_v0(struct beiscsi_offload_params *params, | |||
| 335 | void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, | 335 | void beiscsi_offload_cxn_v2(struct beiscsi_offload_params *params, |
| 336 | struct wrb_handle *pwrb_handle); | 336 | struct wrb_handle *pwrb_handle); |
| 337 | void beiscsi_ue_detect(struct beiscsi_hba *phba); | 337 | void beiscsi_ue_detect(struct beiscsi_hba *phba); |
| 338 | int be_cmd_modify_eq_delay(struct beiscsi_hba *phba, | ||
| 339 | struct be_set_eqd *, int num); | ||
| 338 | 340 | ||
| 339 | #endif | 341 | #endif |
