Skip to content

Commit 5e62d5f

Browse files
committed
IB/mlx4: Create slave AH's directly
Since slave GID's do not exist in the core gid table we can no longer use the core code to help do this without creating inconsistencies. Directly create the AH using mlx4 internal APIs. Signed-off-by: Jason Gunthorpe <[email protected]> Reviewed-by: Jack Morgenstein <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]>
1 parent d9c4404 commit 5e62d5f

File tree

3 files changed

+59
-25
lines changed

3 files changed

+59
-25
lines changed

drivers/infiniband/hw/mlx4/ah.c

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,29 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd,
9696

9797
memcpy(ah->av.eth.mac, ah_attr->roce.dmac, ETH_ALEN);
9898
eth_zero_addr(ah->av.eth.s_mac);
99+
100+
/*
101+
* If sgid_attr is NULL we are being called by mlx4_ib_create_ah_slave
102+
* and we are directly creating an AV for a slave's gid_index.
103+
*/
99104
gid_attr = ah_attr->grh.sgid_attr;
100-
if (is_vlan_dev(gid_attr->ndev))
101-
vlan_tag = vlan_dev_vlan_id(gid_attr->ndev);
102-
memcpy(ah->av.eth.s_mac, gid_attr->ndev->dev_addr, ETH_ALEN);
105+
if (gid_attr) {
106+
if (is_vlan_dev(gid_attr->ndev))
107+
vlan_tag = vlan_dev_vlan_id(gid_attr->ndev);
108+
memcpy(ah->av.eth.s_mac, gid_attr->ndev->dev_addr, ETH_ALEN);
109+
ret = mlx4_ib_gid_index_to_real_index(ibdev, gid_attr);
110+
if (ret < 0)
111+
return ERR_PTR(ret);
112+
ah->av.eth.gid_index = ret;
113+
} else {
114+
/* mlx4_ib_create_ah_slave fills in the s_mac and the vlan */
115+
ah->av.eth.gid_index = ah_attr->grh.sgid_index;
116+
}
103117

104118
if (vlan_tag < 0x1000)
105119
vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13;
106120
ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn |
107121
(rdma_ah_get_port_num(ah_attr) << 24));
108-
ret = mlx4_ib_gid_index_to_real_index(ibdev, gid_attr);
109-
if (ret < 0)
110-
return ERR_PTR(ret);
111-
ah->av.eth.gid_index = ret;
112122
ah->av.eth.vlan = cpu_to_be16(vlan_tag);
113123
ah->av.eth.hop_limit = grh->hop_limit;
114124
if (rdma_ah_get_static_rate(ah_attr)) {
@@ -167,6 +177,40 @@ struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
167177
return create_ib_ah(pd, ah_attr, ah); /* never fails */
168178
}
169179

180+
/* AH's created via this call must be free'd by mlx4_ib_destroy_ah. */
181+
struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
182+
struct rdma_ah_attr *ah_attr,
183+
int slave_sgid_index, u8 *s_mac,
184+
u16 vlan_tag)
185+
{
186+
struct rdma_ah_attr slave_attr = *ah_attr;
187+
struct mlx4_ib_ah *mah;
188+
struct ib_ah *ah;
189+
190+
slave_attr.grh.sgid_attr = NULL;
191+
slave_attr.grh.sgid_index = slave_sgid_index;
192+
ah = mlx4_ib_create_ah(pd, &slave_attr, NULL);
193+
if (IS_ERR(ah))
194+
return ah;
195+
196+
ah->device = pd->device;
197+
ah->pd = pd;
198+
ah->type = ah_attr->type;
199+
mah = to_mah(ah);
200+
201+
/* get rid of force-loopback bit */
202+
mah->av.ib.port_pd &= cpu_to_be32(0x7FFFFFFF);
203+
204+
if (ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE)
205+
memcpy(mah->av.eth.s_mac, s_mac, 6);
206+
207+
if (vlan_tag < 0x1000)
208+
vlan_tag |= (rdma_ah_get_sl(ah_attr) & 7) << 13;
209+
mah->av.eth.vlan = cpu_to_be16(vlan_tag);
210+
211+
return ah;
212+
}
213+
170214
int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
171215
{
172216
struct mlx4_ib_ah *ah = to_mah(ibah);

drivers/infiniband/hw/mlx4/mad.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,13 +1367,10 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
13671367
struct mlx4_mad_snd_buf *sqp_mad;
13681368
struct ib_ah *ah;
13691369
struct ib_qp *send_qp = NULL;
1370-
struct ib_global_route *grh;
13711370
unsigned wire_tx_ix = 0;
13721371
int ret = 0;
13731372
u16 wire_pkey_ix;
13741373
int src_qpnum;
1375-
u8 sgid_index;
1376-
13771374

13781375
sqp_ctx = dev->sriov.sqps[port-1];
13791376

@@ -1394,16 +1391,11 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
13941391
send_qp = sqp->qp;
13951392

13961393
/* create ah */
1397-
grh = rdma_ah_retrieve_grh(attr);
1398-
sgid_index = grh->sgid_index;
1399-
grh->sgid_index = 0;
1400-
ah = rdma_create_ah(sqp_ctx->pd, attr);
1394+
ah = mlx4_ib_create_ah_slave(sqp_ctx->pd, attr,
1395+
rdma_ah_retrieve_grh(attr)->sgid_index,
1396+
s_mac, vlan_id);
14011397
if (IS_ERR(ah))
14021398
return -ENOMEM;
1403-
grh->sgid_index = sgid_index;
1404-
to_mah(ah)->av.ib.gid_index = sgid_index;
1405-
/* get rid of force-loopback bit */
1406-
to_mah(ah)->av.ib.port_pd &= cpu_to_be32(0x7FFFFFFF);
14071399
spin_lock(&sqp->tx_lock);
14081400
if (sqp->tx_ix_head - sqp->tx_ix_tail >=
14091401
(MLX4_NUM_TUNNEL_BUFS - 1))
@@ -1445,12 +1437,6 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
14451437
wr.wr.num_sge = 1;
14461438
wr.wr.opcode = IB_WR_SEND;
14471439
wr.wr.send_flags = IB_SEND_SIGNALED;
1448-
if (s_mac)
1449-
memcpy(to_mah(ah)->av.eth.s_mac, s_mac, 6);
1450-
if (vlan_id < 0x1000)
1451-
vlan_id |= (rdma_ah_get_sl(attr) & 7) << 13;
1452-
to_mah(ah)->av.eth.vlan = cpu_to_be16(vlan_id);
1453-
14541440

14551441
ret = ib_post_send(send_qp, &wr.wr, &bad_wr);
14561442
if (!ret)
@@ -1461,7 +1447,7 @@ int mlx4_ib_send_to_wire(struct mlx4_ib_dev *dev, int slave, u8 port,
14611447
spin_unlock(&sqp->tx_lock);
14621448
sqp->tx_ring[wire_tx_ix].ah = NULL;
14631449
out:
1464-
rdma_destroy_ah(ah);
1450+
mlx4_ib_destroy_ah(ah);
14651451
return ret;
14661452
}
14671453

drivers/infiniband/hw/mlx4/mlx4_ib.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,10 @@ void mlx4_ib_cq_clean(struct mlx4_ib_cq *cq, u32 qpn, struct mlx4_ib_srq *srq);
760760

761761
struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr,
762762
struct ib_udata *udata);
763+
struct ib_ah *mlx4_ib_create_ah_slave(struct ib_pd *pd,
764+
struct rdma_ah_attr *ah_attr,
765+
int slave_sgid_index, u8 *s_mac,
766+
u16 vlan_tag);
763767
int mlx4_ib_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr);
764768
int mlx4_ib_destroy_ah(struct ib_ah *ah);
765769

0 commit comments

Comments
 (0)