int paylen, struct rxe_pkt_info *pkt)
 {
        unsigned int hdr_len;
-       struct sk_buff *skb;
+       struct sk_buff *skb = NULL;
        struct net_device *ndev;
        const struct ib_gid_attr *attr;
        const int port_num = 1;
        attr = rdma_get_gid_attr(&rxe->ib_dev, port_num, av->grh.sgid_index);
        if (IS_ERR(attr))
                return NULL;
-       ndev = attr->ndev;
 
        if (av->network_type == RDMA_NETWORK_IPV4)
                hdr_len = ETH_HLEN + sizeof(struct udphdr) +
                hdr_len = ETH_HLEN + sizeof(struct udphdr) +
                        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),
                        GFP_ATOMIC);
 
-       if (unlikely(!skb))
+       if (unlikely(!skb)) {
+               rcu_read_unlock();
                goto out;
+       }
 
        skb_reserve(skb, hdr_len + LL_RESERVED_SPACE(ndev));
 
        /* FIXME: hold reference to this netdev until life of this skb. */
        skb->dev        = ndev;
+       rcu_read_unlock();
+
        if (av->network_type == RDMA_NETWORK_IPV4)
                skb->protocol = htons(ETH_P_IP);
        else