summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2015-07-22 15:53:48 +0200
committerDavid S. Miller <davem@davemloft.net>2015-07-27 01:29:25 +0200
commit9f5b031770b9108b57881c83dffc02cd90ec3961 (patch)
tree793f828113af4855d38aae0346187b9a00c09e8f /drivers/net
parentnet/mlx4_core: Fix wrong index in propagating port change event to VFs (diff)
downloadlinux-9f5b031770b9108b57881c83dffc02cd90ec3961.tar.xz
linux-9f5b031770b9108b57881c83dffc02cd90ec3961.zip
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: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/cmd.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index 82040137d7d9..0a3202047569 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -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_context *context;
+ long ret_wait;
int err = 0;
down(&cmd->event_sem);
@@ -711,8 +712,20 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
if (err)
goto out_reset;
- if (!wait_for_completion_timeout(&context->done,
- msecs_to_jiffies(timeout))) {
+ if (op == MLX4_CMD_SENSE_PORT) {
+ 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",
op);
if (op == MLX4_CMD_NOP) {