Re: [PATCH rdma-next 5/7] RDMA/rxe: Use rdma_read_gid_attr_ndev_rcu to access netdev

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2019/4/10 21:32, Leon Romanovsky wrote:
On Wed, Apr 10, 2019 at 09:16:26PM +0800, Yanjun Zhu wrote:
On 2019/4/10 16:15, Leon Romanovsky wrote:
From: Parav Pandit <parav@xxxxxxxxxxxx>

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@xxxxxxxxxxxx>
Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx>
---
   drivers/infiniband/sw/rxe/rxe_net.c | 15 ++++++++++++---
   1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index c44139788afc..5a3474f9351b 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -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)
   {
   	unsigned int hdr_len;
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
In the following source code, skb is assigned before it is used. So is it
necessary to initialize it now?
Yes, we need to initialize it, because we have an error unwind path
prior to skb reassignment, see rdma_read_gid_attr_ndev_rcu() in this
patch.

Sure. Agree with you. Thanks.



Zhu Yanjun

   	struct net_device *ndev;
   	const struct ib_gid_attr *attr;
   	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);
   	if (IS_ERR(attr))
   		return NULL;
-	ndev = attr->ndev;
   	if (av->network_type == RDMA_NETWORK_IPV4)
   		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) +
   			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



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux