net/mlx4_core: Protect port type setting by mutex
authorAmir Vadai <amirv@mellanox.com>
Sun, 2 Nov 2014 14:26:14 +0000 (16:26 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 3 Nov 2014 17:28:13 +0000 (12:28 -0500)
We need to protect set_port_type() for concurrency, as the sysfs code could
call it from mutliple contexts in parallel.

The port_mutex is not enough because we need to protect from concurrent
modification of 'info' and stopping of the port sensing work.

Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/main.c

index 90de6e1ad06e9eb0bf002d9c1f87a5d80019fffe..9f821964a1b9e01c94c3f068f83b3c3d2a9c265a 100644 (file)
@@ -901,9 +901,12 @@ static ssize_t set_port_type(struct device *dev,
        struct mlx4_priv *priv = mlx4_priv(mdev);
        enum mlx4_port_type types[MLX4_MAX_PORTS];
        enum mlx4_port_type new_types[MLX4_MAX_PORTS];
+       static DEFINE_MUTEX(set_port_type_mutex);
        int i;
        int err = 0;
 
+       mutex_lock(&set_port_type_mutex);
+
        if (!strcmp(buf, "ib\n"))
                info->tmp_type = MLX4_PORT_TYPE_IB;
        else if (!strcmp(buf, "eth\n"))
@@ -912,7 +915,8 @@ static ssize_t set_port_type(struct device *dev,
                info->tmp_type = MLX4_PORT_TYPE_AUTO;
        else {
                mlx4_err(mdev, "%s is not supported port type\n", buf);
-               return -EINVAL;
+               err = -EINVAL;
+               goto err_out;
        }
 
        mlx4_stop_sense(mdev);
@@ -958,6 +962,9 @@ static ssize_t set_port_type(struct device *dev,
 out:
        mlx4_start_sense(mdev);
        mutex_unlock(&priv->port_mutex);
+err_out:
+       mutex_unlock(&set_port_type_mutex);
+
        return err ? err : count;
 }