summaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/i40iw/i40iw_utils.c
diff options
context:
space:
mode:
authorShiraz Saleem <shiraz.saleem@intel.com>2017-08-08 20:38:45 -0500
committerDoug Ledford <dledford@redhat.com>2017-08-22 15:38:27 -0400
commitd26875b43d45644e87f4c0b6bb2d7abf3c61d529 (patch)
tree47b1dbbe4234afb5e2f458f9d8d63b7ebee614b1 /drivers/infiniband/hw/i40iw/i40iw_utils.c
parentbf808b5039c66f9843cdc30f18c0608dbbf11374 (diff)
downloadlinux-d26875b43d45644e87f4c0b6bb2d7abf3c61d529.tar.bz2
i40iw: Improve CQP timeout logic
The current timeout logic for Control Queue-Pair (CQP) OPs does not take into account whether CQP makes progress but rather blindly waits for a large timeout value, 100000 jiffies for the completion event. Improve this by setting the timeout based on whether the CQP is making progress or not. If the CQP is hung, the timeout will happen sooner, in 5000 jiffies. Each time the CQP progress is detetcted, the timeout extends by 5000 jiffies. Signed-off-by: Shiraz Saleem <shiraz.saleem@intel.com> Signed-off-by: Christopher N Bednarz <christopher.n.bednarz@intel.com> Signed-off-by: Henry Orosco <henry.orosco@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/hw/i40iw/i40iw_utils.c')
-rw-r--r--drivers/infiniband/hw/i40iw/i40iw_utils.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw_utils.c b/drivers/infiniband/hw/i40iw/i40iw_utils.c
index e311ec559f4e..62f1f45b8737 100644
--- a/drivers/infiniband/hw/i40iw/i40iw_utils.c
+++ b/drivers/infiniband/hw/i40iw/i40iw_utils.c
@@ -445,23 +445,29 @@ static int i40iw_wait_event(struct i40iw_device *iwdev,
{
struct cqp_commands_info *info = &cqp_request->info;
struct i40iw_cqp *iwcqp = &iwdev->cqp;
+ struct i40iw_cqp_timeout cqp_timeout;
bool cqp_error = false;
int err_code = 0;
- int timeout_ret = 0;
+ memset(&cqp_timeout, 0, sizeof(cqp_timeout));
+ cqp_timeout.compl_cqp_cmds = iwdev->sc_dev.cqp_cmd_stats[OP_COMPLETED_COMMANDS];
+ do {
+ if (wait_event_timeout(cqp_request->waitq,
+ cqp_request->request_done, CQP_COMPL_WAIT_TIME))
+ break;
- timeout_ret = wait_event_timeout(cqp_request->waitq,
- cqp_request->request_done,
- I40IW_EVENT_TIMEOUT);
- if (!timeout_ret) {
- i40iw_pr_err("error cqp command 0x%x timed out ret = %d\n",
- info->cqp_cmd, timeout_ret);
+ i40iw_check_cqp_progress(&cqp_timeout, &iwdev->sc_dev);
+
+ if (cqp_timeout.count < CQP_TIMEOUT_THRESHOLD)
+ continue;
+
+ i40iw_pr_err("error cqp command 0x%x timed out", info->cqp_cmd);
err_code = -ETIME;
if (!iwdev->reset) {
iwdev->reset = true;
i40iw_request_reset(iwdev);
}
goto done;
- }
+ } while (1);
cqp_error = cqp_request->compl_info.error;
if (cqp_error) {
i40iw_pr_err("error cqp command 0x%x completion maj = 0x%x min=0x%x\n",