mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-02 21:32:58 +00:00
Selectivly backport fix for firmware command hang when switching from
polling-based firmware commands to event based firmware commands. This is a direct commit. Linux commit: a7e1f04905e5b2b90251974dddde781301b6be37 Sponsored by: Mellanox Technologies
This commit is contained in:
parent
c854065bfa
commit
82101a443a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=339086
@ -794,14 +794,19 @@ int __mlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
|
||||
return -EIO;
|
||||
|
||||
if (!mlx4_is_mfunc(dev) || (native && mlx4_is_master(dev))) {
|
||||
int ret;
|
||||
|
||||
down_read(&mlx4_priv(dev)->cmd.switch_sem);
|
||||
if (mlx4_priv(dev)->cmd.use_events)
|
||||
return mlx4_cmd_wait(dev, in_param, out_param,
|
||||
out_is_imm, in_modifier,
|
||||
op_modifier, op, timeout);
|
||||
ret = mlx4_cmd_wait(dev, in_param, out_param,
|
||||
out_is_imm, in_modifier,
|
||||
op_modifier, op, timeout);
|
||||
else
|
||||
return mlx4_cmd_poll(dev, in_param, out_param,
|
||||
out_is_imm, in_modifier,
|
||||
op_modifier, op, timeout);
|
||||
ret = mlx4_cmd_poll(dev, in_param, out_param,
|
||||
out_is_imm, in_modifier,
|
||||
op_modifier, op, timeout);
|
||||
up_read(&mlx4_priv(dev)->cmd.switch_sem);
|
||||
return ret;
|
||||
}
|
||||
return mlx4_slave_cmd(dev, in_param, out_param, out_is_imm,
|
||||
in_modifier, op_modifier, op, timeout);
|
||||
@ -2253,6 +2258,7 @@ int mlx4_cmd_init(struct mlx4_dev *dev)
|
||||
{
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
|
||||
init_rwsem(&priv->cmd.switch_sem);
|
||||
mutex_init(&priv->cmd.hcr_mutex);
|
||||
mutex_init(&priv->cmd.slave_cmd_mutex);
|
||||
sema_init(&priv->cmd.poll_sem, 1);
|
||||
@ -2351,6 +2357,7 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev)
|
||||
if (!priv->cmd.context)
|
||||
return -ENOMEM;
|
||||
|
||||
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;
|
||||
@ -2370,6 +2377,7 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev)
|
||||
|
||||
down(&priv->cmd.poll_sem);
|
||||
priv->cmd.use_events = 1;
|
||||
up_write(&priv->cmd.switch_sem);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -2382,6 +2390,7 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev)
|
||||
struct mlx4_priv *priv = mlx4_priv(dev);
|
||||
int i;
|
||||
|
||||
down_write(&priv->cmd.switch_sem);
|
||||
priv->cmd.use_events = 0;
|
||||
|
||||
for (i = 0; i < priv->cmd.max_cmds; ++i)
|
||||
@ -2390,6 +2399,7 @@ void mlx4_cmd_use_polling(struct mlx4_dev *dev)
|
||||
kfree(priv->cmd.context);
|
||||
|
||||
up(&priv->cmd.poll_sem);
|
||||
up_write(&priv->cmd.switch_sem);
|
||||
}
|
||||
|
||||
struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev)
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/mlx4/device.h>
|
||||
#include <linux/mlx4/driver.h>
|
||||
#include <linux/mlx4/doorbell.h>
|
||||
@ -596,6 +597,7 @@ struct mlx4_cmd {
|
||||
struct mutex slave_cmd_mutex;
|
||||
struct semaphore poll_sem;
|
||||
struct semaphore event_sem;
|
||||
struct rw_semaphore switch_sem;
|
||||
int max_cmds;
|
||||
spinlock_t context_lock;
|
||||
int free_head;
|
||||
|
Loading…
Reference in New Issue
Block a user