Skip to content

Commit d585df1

Browse files
Jack Morgensteindavem330
authored andcommitted
net/mlx4_core: Avoid command timeouts during VF driver device shutdown
Some Hypervisors detach VFs from VMs by instantly causing an FLR event to be generated for a VF. In the mlx4 case, this will cause that VF's comm channel to be disabled before the VM has an opportunity to invoke the VF device's "shutdown" method. The result is that the VF driver on the VM will experience a command timeout during the shutdown process when the Hypervisor does not deliver a command-completion event to the VM. To avoid FW command timeouts on the VM when the driver's shutdown method is invoked, we detect the absence of the VF's comm channel at the very start of the shutdown process. If the comm-channel has already been disabled, we cause all FW commands during the device shutdown process to immediately return success (and thus avoid all command timeouts). Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Tariq Toukan <tariqt@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 6415aa5 commit d585df1

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

drivers/net/ethernet/mellanox/mlx4/catas.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ static int mlx4_reset_slave(struct mlx4_dev *dev)
158158
return -ETIMEDOUT;
159159
}
160160

161-
static int mlx4_comm_internal_err(u32 slave_read)
161+
int mlx4_comm_internal_err(u32 slave_read)
162162
{
163163
return (u32)COMM_CHAN_EVENT_INTERNAL_ERR ==
164164
(slave_read & (u32)COMM_CHAN_EVENT_INTERNAL_ERR) ? 1 : 0;

drivers/net/ethernet/mellanox/mlx4/intf.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,18 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
222222
return;
223223

224224
mlx4_stop_catas_poll(dev);
225+
if (dev->persist->interface_state & MLX4_INTERFACE_STATE_DELETION &&
226+
mlx4_is_slave(dev)) {
227+
/* In mlx4_remove_one on a VF */
228+
u32 slave_read =
229+
swab32(readl(&mlx4_priv(dev)->mfunc.comm->slave_read));
230+
231+
if (mlx4_comm_internal_err(slave_read)) {
232+
mlx4_dbg(dev, "%s: comm channel is down, entering error state.\n",
233+
__func__);
234+
mlx4_enter_error_state(dev->persist);
235+
}
236+
}
225237
mutex_lock(&intf_mutex);
226238

227239
list_for_each_entry(intf, &intf_list, list)

drivers/net/ethernet/mellanox/mlx4/mlx4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ void mlx4_qp_event(struct mlx4_dev *dev, u32 qpn, int event_type);
12201220
void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
12211221

12221222
void mlx4_enter_error_state(struct mlx4_dev_persistent *persist);
1223+
int mlx4_comm_internal_err(u32 slave_read);
12231224

12241225
int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
12251226
enum mlx4_port_type *type);

0 commit comments

Comments
 (0)