Skip to content

Commit

Permalink
RDMA/rxe: Fix skb lifetime in rxe_rcv_mcast_pkt()
Browse files Browse the repository at this point in the history
[ Upstream commit e7ec96f ]

The changes referenced below replaced sbk_clone)_ by taking additional
references, passing the skb along and then freeing the skb. This
deleted the packets before they could be processed and additionally
passed bad data in each packet. Since pkt is stored in skb->cb
changing pkt->qp changed it for all the packets.

Replace skb_get() by sbk_clone() in rxe_rcv_mcast_pkt() for cases where
multiple QPs are receiving multicast packets on the same address.

Delete kfree_skb() because the packets need to live until they have been
processed by each QP. They are freed later.

Fixes: 86af617 ("IB/rxe: remove unnecessary skb_clone")
Fixes: fe896ce ("IB/rxe: replace refcount_inc with skb_get")
Link: https://lore.kernel.org/r/20201008203651.256958-1-rpearson@hpe.com
Signed-off-by: Bob Pearson <rpearson@hpe.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Bob Pearson authored and gregkh committed Oct 29, 2020
1 parent 1407e22 commit 982f243
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions drivers/infiniband/sw/rxe/rxe_recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
struct rxe_mc_elem *mce;
struct rxe_qp *qp;
union ib_gid dgid;
struct sk_buff *per_qp_skb;
struct rxe_pkt_info *per_qp_pkt;
int err;

if (skb->protocol == htons(ETH_P_IP))
Expand Down Expand Up @@ -309,21 +311,26 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
if (err)
continue;

/* if *not* the last qp in the list
* increase the users of the skb then post to the next qp
/* for all but the last qp create a new clone of the
* skb and pass to the qp.
*/
if (mce->qp_list.next != &mcg->qp_list)
skb_get(skb);
per_qp_skb = skb_clone(skb, GFP_ATOMIC);
else
per_qp_skb = skb;

pkt->qp = qp;
per_qp_pkt = SKB_TO_PKT(per_qp_skb);
per_qp_pkt->qp = qp;
rxe_add_ref(qp);
rxe_rcv_pkt(pkt, skb);
rxe_rcv_pkt(per_qp_pkt, per_qp_skb);
}

spin_unlock_bh(&mcg->mcg_lock);

rxe_drop_ref(mcg); /* drop ref from rxe_pool_get_key. */

return;

err1:
kfree_skb(skb);
}
Expand Down

0 comments on commit 982f243

Please sign in to comment.