RDMA/rxe: Use rdma_read_gid_attr_ndev_rcu to access netdev
Use rdma_read_gid_attr_ndev_rcu() to access netdevice attached to GID entry under rcu lock. This ensures that while working on the netdevice of the GID, it doesn't get freed. Signed-off-by: Parav Pandit <parav@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
adb4a57a7a
commit
dab2175800
@ -458,7 +458,7 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,
|
|||||||
int paylen, struct rxe_pkt_info *pkt)
|
int paylen, struct rxe_pkt_info *pkt)
|
||||||
{
|
{
|
||||||
unsigned int hdr_len;
|
unsigned int hdr_len;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb = NULL;
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
const struct ib_gid_attr *attr;
|
const struct ib_gid_attr *attr;
|
||||||
const int port_num = 1;
|
const int port_num = 1;
|
||||||
@ -466,7 +466,6 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,
|
|||||||
attr = rdma_get_gid_attr(&rxe->ib_dev, port_num, av->grh.sgid_index);
|
attr = rdma_get_gid_attr(&rxe->ib_dev, port_num, av->grh.sgid_index);
|
||||||
if (IS_ERR(attr))
|
if (IS_ERR(attr))
|
||||||
return NULL;
|
return NULL;
|
||||||
ndev = attr->ndev;
|
|
||||||
|
|
||||||
if (av->network_type == RDMA_NETWORK_IPV4)
|
if (av->network_type == RDMA_NETWORK_IPV4)
|
||||||
hdr_len = ETH_HLEN + sizeof(struct udphdr) +
|
hdr_len = ETH_HLEN + sizeof(struct udphdr) +
|
||||||
@ -475,16 +474,26 @@ struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,
|
|||||||
hdr_len = ETH_HLEN + sizeof(struct udphdr) +
|
hdr_len = ETH_HLEN + sizeof(struct udphdr) +
|
||||||
sizeof(struct ipv6hdr);
|
sizeof(struct ipv6hdr);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
ndev = rdma_read_gid_attr_ndev_rcu(attr);
|
||||||
|
if (IS_ERR(ndev)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
skb = alloc_skb(paylen + hdr_len + LL_RESERVED_SPACE(ndev),
|
skb = alloc_skb(paylen + hdr_len + LL_RESERVED_SPACE(ndev),
|
||||||
GFP_ATOMIC);
|
GFP_ATOMIC);
|
||||||
|
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb)) {
|
||||||
|
rcu_read_unlock();
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
skb_reserve(skb, hdr_len + LL_RESERVED_SPACE(ndev));
|
skb_reserve(skb, hdr_len + LL_RESERVED_SPACE(ndev));
|
||||||
|
|
||||||
/* FIXME: hold reference to this netdev until life of this skb. */
|
/* FIXME: hold reference to this netdev until life of this skb. */
|
||||||
skb->dev = ndev;
|
skb->dev = ndev;
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (av->network_type == RDMA_NETWORK_IPV4)
|
if (av->network_type == RDMA_NETWORK_IPV4)
|
||||||
skb->protocol = htons(ETH_P_IP);
|
skb->protocol = htons(ETH_P_IP);
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user