mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-23 11:08:07 +00:00
IB: Make ib_init_ah_attr_from_wc set sgid_attr
The work completion is inspected to determine what dgid table entry was used to receieve the packet, produces a sgid_attr that matches and sticks it in the ah_attr. All callers of this function are now required to release the ah_attr on success. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
This commit is contained in:
parent
70324739ac
commit
b740321765
@ -1091,6 +1091,9 @@ retest:
|
|||||||
wait_for_completion(&cm_id_priv->comp);
|
wait_for_completion(&cm_id_priv->comp);
|
||||||
while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
|
while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
|
||||||
cm_free_work(work);
|
cm_free_work(work);
|
||||||
|
|
||||||
|
rdma_destroy_ah_attr(&cm_id_priv->av.ah_attr);
|
||||||
|
rdma_destroy_ah_attr(&cm_id_priv->alt_av.ah_attr);
|
||||||
kfree(cm_id_priv->private_data);
|
kfree(cm_id_priv->private_data);
|
||||||
kfree(cm_id_priv);
|
kfree(cm_id_priv);
|
||||||
}
|
}
|
||||||
|
@ -268,6 +268,7 @@ static void recv_handler(struct ib_mad_agent *agent,
|
|||||||
packet->mad.hdr.traffic_class = grh->traffic_class;
|
packet->mad.hdr.traffic_class = grh->traffic_class;
|
||||||
memcpy(packet->mad.hdr.gid, &grh->dgid, 16);
|
memcpy(packet->mad.hdr.gid, &grh->dgid, 16);
|
||||||
packet->mad.hdr.flow_label = cpu_to_be32(grh->flow_label);
|
packet->mad.hdr.flow_label = cpu_to_be32(grh->flow_label);
|
||||||
|
rdma_destroy_ah_attr(&ah_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (queue_packet(file, agent, packet))
|
if (queue_packet(file, agent, packet))
|
||||||
|
@ -636,16 +636,16 @@ static bool find_gid_index(const union ib_gid *gid,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_sgid_index_from_eth(struct ib_device *device, u8 port_num,
|
static const struct ib_gid_attr *
|
||||||
u16 vlan_id, const union ib_gid *sgid,
|
get_sgid_attr_from_eth(struct ib_device *device, u8 port_num,
|
||||||
enum ib_gid_type gid_type,
|
u16 vlan_id, const union ib_gid *sgid,
|
||||||
u16 *gid_index)
|
enum ib_gid_type gid_type)
|
||||||
{
|
{
|
||||||
struct find_gid_index_context context = {.vlan_id = vlan_id,
|
struct find_gid_index_context context = {.vlan_id = vlan_id,
|
||||||
.gid_type = gid_type};
|
.gid_type = gid_type};
|
||||||
|
|
||||||
return ib_find_gid_by_filter(device, sgid, port_num, find_gid_index,
|
return rdma_find_gid_by_filter(device, sgid, port_num, find_gid_index,
|
||||||
&context, gid_index);
|
&context);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
|
int ib_get_gids_from_rdma_hdr(const union rdma_network_hdr *hdr,
|
||||||
@ -689,37 +689,24 @@ EXPORT_SYMBOL(ib_get_gids_from_rdma_hdr);
|
|||||||
static int ib_resolve_unicast_gid_dmac(struct ib_device *device,
|
static int ib_resolve_unicast_gid_dmac(struct ib_device *device,
|
||||||
struct rdma_ah_attr *ah_attr)
|
struct rdma_ah_attr *ah_attr)
|
||||||
{
|
{
|
||||||
struct ib_gid_attr sgid_attr;
|
struct ib_global_route *grh = rdma_ah_retrieve_grh(ah_attr);
|
||||||
struct ib_global_route *grh;
|
const struct ib_gid_attr *sgid_attr = grh->sgid_attr;
|
||||||
int hop_limit = 0xff;
|
int hop_limit = 0xff;
|
||||||
union ib_gid sgid;
|
int ret = 0;
|
||||||
int ret;
|
|
||||||
|
|
||||||
grh = rdma_ah_retrieve_grh(ah_attr);
|
|
||||||
|
|
||||||
ret = ib_get_cached_gid(device, rdma_ah_get_port_num(ah_attr),
|
|
||||||
grh->sgid_index, &sgid, &sgid_attr);
|
|
||||||
if (ret || !sgid_attr.ndev) {
|
|
||||||
if (!ret)
|
|
||||||
ret = -ENXIO;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If destination is link local and source GID is RoCEv1,
|
/* If destination is link local and source GID is RoCEv1,
|
||||||
* IP stack is not used.
|
* IP stack is not used.
|
||||||
*/
|
*/
|
||||||
if (rdma_link_local_addr((struct in6_addr *)grh->dgid.raw) &&
|
if (rdma_link_local_addr((struct in6_addr *)grh->dgid.raw) &&
|
||||||
sgid_attr.gid_type == IB_GID_TYPE_ROCE) {
|
sgid_attr->gid_type == IB_GID_TYPE_ROCE) {
|
||||||
rdma_get_ll_mac((struct in6_addr *)grh->dgid.raw,
|
rdma_get_ll_mac((struct in6_addr *)grh->dgid.raw,
|
||||||
ah_attr->roce.dmac);
|
ah_attr->roce.dmac);
|
||||||
goto done;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = rdma_addr_find_l2_eth_by_grh(&sgid, &grh->dgid,
|
ret = rdma_addr_find_l2_eth_by_grh(&sgid_attr->gid, &grh->dgid,
|
||||||
ah_attr->roce.dmac,
|
ah_attr->roce.dmac,
|
||||||
sgid_attr.ndev, &hop_limit);
|
sgid_attr->ndev, &hop_limit);
|
||||||
done:
|
|
||||||
dev_put(sgid_attr.ndev);
|
|
||||||
|
|
||||||
grh->hop_limit = hop_limit;
|
grh->hop_limit = hop_limit;
|
||||||
return ret;
|
return ret;
|
||||||
@ -734,16 +721,18 @@ done:
|
|||||||
* as sgid and, sgid is used as dgid because sgid contains destinations
|
* as sgid and, sgid is used as dgid because sgid contains destinations
|
||||||
* GID whom to respond to.
|
* GID whom to respond to.
|
||||||
*
|
*
|
||||||
|
* On success the caller is responsible to call rdma_destroy_ah_attr on the
|
||||||
|
* attr.
|
||||||
*/
|
*/
|
||||||
int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num,
|
int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num,
|
||||||
const struct ib_wc *wc, const struct ib_grh *grh,
|
const struct ib_wc *wc, const struct ib_grh *grh,
|
||||||
struct rdma_ah_attr *ah_attr)
|
struct rdma_ah_attr *ah_attr)
|
||||||
{
|
{
|
||||||
u32 flow_class;
|
u32 flow_class;
|
||||||
u16 gid_index;
|
|
||||||
int ret;
|
int ret;
|
||||||
enum rdma_network_type net_type = RDMA_NETWORK_IB;
|
enum rdma_network_type net_type = RDMA_NETWORK_IB;
|
||||||
enum ib_gid_type gid_type = IB_GID_TYPE_IB;
|
enum ib_gid_type gid_type = IB_GID_TYPE_IB;
|
||||||
|
const struct ib_gid_attr *sgid_attr;
|
||||||
int hoplimit = 0xff;
|
int hoplimit = 0xff;
|
||||||
union ib_gid dgid;
|
union ib_gid dgid;
|
||||||
union ib_gid sgid;
|
union ib_gid sgid;
|
||||||
@ -774,40 +763,49 @@ int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num,
|
|||||||
if (!(wc->wc_flags & IB_WC_GRH))
|
if (!(wc->wc_flags & IB_WC_GRH))
|
||||||
return -EPROTOTYPE;
|
return -EPROTOTYPE;
|
||||||
|
|
||||||
ret = get_sgid_index_from_eth(device, port_num,
|
sgid_attr = get_sgid_attr_from_eth(device, port_num,
|
||||||
vlan_id, &dgid,
|
vlan_id, &dgid,
|
||||||
gid_type, &gid_index);
|
gid_type);
|
||||||
if (ret)
|
if (IS_ERR(sgid_attr))
|
||||||
return ret;
|
return PTR_ERR(sgid_attr);
|
||||||
|
|
||||||
flow_class = be32_to_cpu(grh->version_tclass_flow);
|
flow_class = be32_to_cpu(grh->version_tclass_flow);
|
||||||
rdma_ah_set_grh(ah_attr, &sgid,
|
rdma_move_grh_sgid_attr(ah_attr,
|
||||||
flow_class & 0xFFFFF,
|
&sgid,
|
||||||
(u8)gid_index, hoplimit,
|
flow_class & 0xFFFFF,
|
||||||
(flow_class >> 20) & 0xFF);
|
hoplimit,
|
||||||
return ib_resolve_unicast_gid_dmac(device, ah_attr);
|
(flow_class >> 20) & 0xFF,
|
||||||
|
sgid_attr);
|
||||||
|
|
||||||
|
ret = ib_resolve_unicast_gid_dmac(device, ah_attr);
|
||||||
|
if (ret)
|
||||||
|
rdma_destroy_ah_attr(ah_attr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
rdma_ah_set_dlid(ah_attr, wc->slid);
|
rdma_ah_set_dlid(ah_attr, wc->slid);
|
||||||
rdma_ah_set_path_bits(ah_attr, wc->dlid_path_bits);
|
rdma_ah_set_path_bits(ah_attr, wc->dlid_path_bits);
|
||||||
|
|
||||||
if (wc->wc_flags & IB_WC_GRH) {
|
if ((wc->wc_flags & IB_WC_GRH) == 0)
|
||||||
if (dgid.global.interface_id != cpu_to_be64(IB_SA_WELL_KNOWN_GUID)) {
|
return 0;
|
||||||
ret = ib_find_cached_gid_by_port(device, &dgid,
|
|
||||||
IB_GID_TYPE_IB,
|
|
||||||
port_num, NULL,
|
|
||||||
&gid_index);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
gid_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
flow_class = be32_to_cpu(grh->version_tclass_flow);
|
if (dgid.global.interface_id !=
|
||||||
rdma_ah_set_grh(ah_attr, &sgid,
|
cpu_to_be64(IB_SA_WELL_KNOWN_GUID)) {
|
||||||
|
sgid_attr = rdma_find_gid_by_port(
|
||||||
|
device, &dgid, IB_GID_TYPE_IB, port_num, NULL);
|
||||||
|
} else
|
||||||
|
sgid_attr = rdma_get_gid_attr(device, port_num, 0);
|
||||||
|
|
||||||
|
if (IS_ERR(sgid_attr))
|
||||||
|
return PTR_ERR(sgid_attr);
|
||||||
|
flow_class = be32_to_cpu(grh->version_tclass_flow);
|
||||||
|
rdma_move_grh_sgid_attr(ah_attr,
|
||||||
|
&sgid,
|
||||||
flow_class & 0xFFFFF,
|
flow_class & 0xFFFFF,
|
||||||
(u8)gid_index, hoplimit,
|
hoplimit,
|
||||||
(flow_class >> 20) & 0xFF);
|
(flow_class >> 20) & 0xFF,
|
||||||
}
|
sgid_attr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -860,13 +858,17 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, const struct ib_wc *wc,
|
|||||||
const struct ib_grh *grh, u8 port_num)
|
const struct ib_grh *grh, u8 port_num)
|
||||||
{
|
{
|
||||||
struct rdma_ah_attr ah_attr;
|
struct rdma_ah_attr ah_attr;
|
||||||
|
struct ib_ah *ah;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ib_init_ah_attr_from_wc(pd->device, port_num, wc, grh, &ah_attr);
|
ret = ib_init_ah_attr_from_wc(pd->device, port_num, wc, grh, &ah_attr);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
|
|
||||||
return rdma_create_ah(pd, &ah_attr);
|
ah = rdma_create_ah(pd, &ah_attr);
|
||||||
|
|
||||||
|
rdma_destroy_ah_attr(&ah_attr);
|
||||||
|
return ah;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ib_create_ah_from_wc);
|
EXPORT_SYMBOL(ib_create_ah_from_wc);
|
||||||
|
|
||||||
|
@ -3150,6 +3150,13 @@ int ib_get_rdma_header_version(const union rdma_network_hdr *hdr);
|
|||||||
* ignored unless the work completion indicates that the GRH is valid.
|
* ignored unless the work completion indicates that the GRH is valid.
|
||||||
* @ah_attr: Returned attributes that can be used when creating an address
|
* @ah_attr: Returned attributes that can be used when creating an address
|
||||||
* handle for replying to the message.
|
* handle for replying to the message.
|
||||||
|
* When ib_init_ah_attr_from_wc() returns success,
|
||||||
|
* (a) for IB link layer it optionally contains a reference to SGID attribute
|
||||||
|
* when GRH is present for IB link layer.
|
||||||
|
* (b) for RoCE link layer it contains a reference to SGID attribute.
|
||||||
|
* User must invoke rdma_cleanup_ah_attr_gid_attr() to release reference to SGID
|
||||||
|
* attributes which are initialized using ib_init_ah_attr_from_wc().
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num,
|
int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num,
|
||||||
const struct ib_wc *wc, const struct ib_grh *grh,
|
const struct ib_wc *wc, const struct ib_grh *grh,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user