Skip to content

Commit 9eb7f8e

Browse files
Andrew Boyerdledford
authored andcommitted
IB/rxe: Move refcounting earlier in rxe_send()
The network stack will call nskb's destructor, rxe_skb_tx_dtor(), if the packet gets dropped by ip_local_out()/ip6_local_out(). Thus we need to add the QP ref before output to avoid extra dereferences during network congestion. This could lead to unwanted destruction of the QP. Fix up the skb_out accounting, too. Fixes: fda85ce ("IB/rxe: Fix kernel panic from skb destructor") Signed-off-by: Andrew Boyer <[email protected]> Acked-by: Moni Shoua <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent 0208da9 commit 9eb7f8e

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

drivers/infiniband/sw/rxe/rxe_net.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,17 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
460460
nskb->destructor = rxe_skb_tx_dtor;
461461
nskb->sk = pkt->qp->sk->sk;
462462

463+
rxe_add_ref(pkt->qp);
464+
atomic_inc(&pkt->qp->skb_out);
465+
463466
if (av->network_type == RDMA_NETWORK_IPV4) {
464467
err = ip_local_out(dev_net(skb_dst(skb)->dev), nskb->sk, nskb);
465468
} else if (av->network_type == RDMA_NETWORK_IPV6) {
466469
err = ip6_local_out(dev_net(skb_dst(skb)->dev), nskb->sk, nskb);
467470
} else {
468471
pr_err("Unknown layer 3 protocol: %d\n", av->network_type);
472+
atomic_dec(&pkt->qp->skb_out);
473+
rxe_drop_ref(pkt->qp);
469474
kfree_skb(nskb);
470475
return -EINVAL;
471476
}
@@ -475,10 +480,7 @@ int rxe_send(struct rxe_dev *rxe, struct rxe_pkt_info *pkt, struct sk_buff *skb)
475480
return -EAGAIN;
476481
}
477482

478-
rxe_add_ref(pkt->qp);
479-
atomic_inc(&pkt->qp->skb_out);
480483
kfree_skb(skb);
481-
482484
return 0;
483485
}
484486

0 commit comments

Comments
 (0)