Commit 9f5b0317 authored by Jack Morgenstein's avatar Jack Morgenstein Committed by David S. Miller

net/mlx4_core: Relieve cpu load average on the port sending flow

When a port is not attached, the FW requires a longer than usual time to
execute the SENSE_PORT command. In the command flow, the
wait_for_completion_timeout call used in mlx4_cmd_wait puts the kernel
thread into the uninterruptible state during this time. This, in turn,
due to the computation method, causes the CPU load average to increase.

Fix this by using wait_for_completion_interruptible_timeout() for the
SENSE_PORT command, which puts the thread in the interruptible state.
In this state, the thread does not contribute to the CPU load average.

Treat the interrupted case as if the SENSE_PORT command returned
port_type = NONE.

Fix suggested by Gideon Naim <gideonn@mellanox.com> and
Bart Van Assche <bart.vanassche@sandisk.com>.
Signed-off-by: default avatarJack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1c1bf349
...@@ -686,6 +686,7 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param, ...@@ -686,6 +686,7 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
{ {
struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd; struct mlx4_cmd *cmd = &mlx4_priv(dev)->cmd;
struct mlx4_cmd_context *context; struct mlx4_cmd_context *context;
long ret_wait;
int err = 0; int err = 0;
down(&cmd->event_sem); down(&cmd->event_sem);
...@@ -711,8 +712,20 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param, ...@@ -711,8 +712,20 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
if (err) if (err)
goto out_reset; goto out_reset;
if (!wait_for_completion_timeout(&context->done, if (op == MLX4_CMD_SENSE_PORT) {
msecs_to_jiffies(timeout))) { ret_wait =
wait_for_completion_interruptible_timeout(&context->done,
msecs_to_jiffies(timeout));
if (ret_wait < 0) {
context->fw_status = 0;
context->out_param = 0;
context->result = 0;
}
} else {
ret_wait = (long)wait_for_completion_timeout(&context->done,
msecs_to_jiffies(timeout));
}
if (!ret_wait) {
mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n", mlx4_warn(dev, "command 0x%x timed out (go bit not cleared)\n",
op); op);
if (op == MLX4_CMD_NOP) { if (op == MLX4_CMD_NOP) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment