From 7eeae4b5510ae0841d0b85d7322313c3dbcc1f5b Mon Sep 17 00:00:00 2001 From: Matan Barak Date: Tue, 23 Sep 2014 11:56:50 +0300 Subject: [PATCH] net/mlx4: When issuing commands use rwsem insteam of rw spinlocks The mlx4 drivers use a read_lock while issuing commands, but when a lot of commands are issued simultaneously, the mlx4 driver could sleep. In order to resolve this "sleep while holding spin-lock" issue, we replace this spinlock with read-write semaphore. Fixes: 2393fac27a97 ('net/mlx4: Switching between sending commands via polling and events may results in hung tasks') Signed-off-by: Matan Barak (Ported from Mellanox OFED 2.4) Signed-off-by: Mukesh Kacker --- drivers/net/ethernet/mellanox/mlx4/cmd.c | 14 +++++++------- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 372443c285395..d79e6b22bf81e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -807,7 +807,7 @@ int __mlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, op_modifier); else { int ret; - read_lock(&mlx4_priv(dev)->cmd.switch_lock); + down_read(&mlx4_priv(dev)->cmd.switch_sem); if (mlx4_priv(dev)->cmd.use_events) ret = mlx4_cmd_wait(dev, in_param, out_param, out_is_imm, in_modifier, @@ -816,7 +816,7 @@ int __mlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, ret = mlx4_cmd_poll(dev, in_param, out_param, out_is_imm, in_modifier, op_modifier, op, timeout); - read_unlock(&mlx4_priv(dev)->cmd.switch_lock); + up_read(&mlx4_priv(dev)->cmd.switch_sem); return ret; } } @@ -2475,7 +2475,7 @@ int mlx4_cmd_init(struct mlx4_dev *dev) int flags = 0; if (!priv->cmd.initialized) { - rwlock_init(&priv->cmd.switch_lock); + init_rwsem(&priv->cmd.switch_sem); mutex_init(&priv->cmd.slave_cmd_mutex); sema_init(&priv->cmd.poll_sem, 1); priv->cmd.use_events = 0; @@ -2605,7 +2605,7 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev) if (!priv->cmd.context) return -ENOMEM; - write_lock(&priv->cmd.switch_lock); + down_write(&priv->cmd.switch_sem); for (i = 0; i < priv->cmd.max_cmds; ++i) { priv->cmd.context[i].token = i; priv->cmd.context[i].next = i + 1; @@ -2630,7 +2630,7 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev) down(&priv->cmd.poll_sem); priv->cmd.use_events = 1; - write_unlock(&priv->cmd.switch_lock); + up_write(&priv->cmd.switch_sem); return err; } @@ -2643,7 +2643,7 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); int i; - write_lock(&priv->cmd.switch_lock); + down_write(&priv->cmd.switch_sem); priv->cmd.use_events = 0; for (i = 0; i < priv->cmd.max_cmds; ++i) @@ -2652,7 +2652,7 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev) kfree(priv->cmd.context); up(&priv->cmd.poll_sem); - write_unlock(&priv->cmd.switch_lock); + up_write(&priv->cmd.switch_sem); } struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev) diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index b38e385147ccb..7370460bebc7d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -612,7 +613,7 @@ struct mlx4_cmd { struct mutex slave_cmd_mutex; struct semaphore poll_sem; struct semaphore event_sem; - rwlock_t switch_lock; + struct rw_semaphore switch_sem; int max_cmds; spinlock_t context_lock; int free_head; -- 2.51.0