@@ -670,6 +670,7 @@ static void cmd_work_handler(struct work
int alloc_ret;
int cmd_mode;
+ complete(&ent->handling);
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
down(sem);
if (!ent->page_queue) {
@@ -769,6 +770,12 @@ static int wait_func(struct mlx5_core_de
struct mlx5_cmd *cmd = &dev->cmd;
int err;
+ if (!wait_for_completion_timeout(&ent->handling, timeout) &&
+ cancel_work_sync(&ent->work)) {
+ ent->ret = -ECANCELED;
+ goto out_err;
+ }
+
if (cmd->mode == CMD_MODE_POLLING) {
wait_for_completion(&ent->done);
} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
@@ -776,12 +783,17 @@ static int wait_func(struct mlx5_core_de
mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
}
+out_err:
err = ent->ret;
if (err == -ETIMEDOUT) {
mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
mlx5_command_str(msg_to_opcode(ent->in)),
msg_to_opcode(ent->in));
+ } else if (err == -ECANCELED) {
+ mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n",
+ mlx5_command_str(msg_to_opcode(ent->in)),
+ msg_to_opcode(ent->in));
}
mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
err, deliv_status_to_str(ent->status), ent->status);
@@ -826,6 +838,7 @@ static int mlx5_cmd_invoke(struct mlx5_c
ent->token = token;
+ init_completion(&ent->handling);
if (!callback)
init_completion(&ent->done);
@@ -841,6 +854,8 @@ static int mlx5_cmd_invoke(struct mlx5_c
if (callback)
goto out;
+ if (err == -ECANCELED)
+ goto out_free;
err = wait_func(dev, ent);
if (err == -ETIMEDOUT)
@@ -569,6 +569,7 @@ struct mlx5_cmd_work_ent {
struct delayed_work cb_timeout_work;
void *context;
int idx;
+ struct completion handling;
struct completion done;
struct mlx5_cmd *cmd;
struct work_struct work;