mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-04 18:19:28 +09:00
IB/mlx4: Fix error flow when sending mads under SRIOV
commita6100603a4upstream. Fix mad send error flow to prevent double freeing address handles, and leaking tx_ring entries when SRIOV is active. If ib_mad_post_send fails, the address handle pointer in the tx_ring entry must be set to NULL (or there will be a double-free) and tx_tail must be incremented (or there will be a leak of tx_ring entries). The tx_ring is handled the same way in the send-completion handler. Fixes:37bfc7c1e8("IB/mlx4: SR-IOV multiplex and demultiplex MADs") Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Reviewed-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
155c27dd55
commit
d057209617
@@ -526,7 +526,7 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
|
||||
tun_tx_ix = (++tun_qp->tx_ix_head) & (MLX4_NUM_TUNNEL_BUFS - 1);
|
||||
spin_unlock(&tun_qp->tx_lock);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto end;
|
||||
|
||||
tun_mad = (struct mlx4_rcv_tunnel_mad *) (tun_qp->tx_ring[tun_tx_ix].buf.addr);
|
||||
if (tun_qp->tx_ring[tun_tx_ix].ah)
|
||||
@@ -595,9 +595,15 @@ int mlx4_ib_send_to_slave(struct mlx4_ib_dev *dev, int slave, u8 port,
|
||||
wr.wr.send_flags = IB_SEND_SIGNALED;
|
||||
|
||||
ret = ib_post_send(src_qp, &wr.wr, &bad_wr);
|
||||
out:
|
||||
if (ret)
|
||||
ib_destroy_ah(ah);
|
||||
if (!ret)
|
||||
return 0;
|
||||
out:
|
||||
spin_lock(&tun_qp->tx_lock);
|
||||
tun_qp->tx_ix_tail++;
|
||||
spin_unlock(&tun_qp->tx_lock);
|
||||
tun_qp->tx_ring[tun_tx_ix].ah = NULL;
|
||||
end:
|
||||
ib_destroy_ah(ah);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1278,9 +1284,15 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
|
||||
|
||||
|
||||
ret = ib_post_send(send_qp, &wr.wr, &bad_wr);
|
||||
if (!ret)
|
||||
return 0;
|
||||
|
||||
spin_lock(&sqp->tx_lock);
|
||||
sqp->tx_ix_tail++;
|
||||
spin_unlock(&sqp->tx_lock);
|
||||
sqp->tx_ring[wire_tx_ix].ah = NULL;
|
||||
out:
|
||||
if (ret)
|
||||
ib_destroy_ah(ah);
|
||||
ib_destroy_ah(ah);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user