In mcast recv process, the function skb_clone is used. In fact, the refcount can be increased to replace cloning a new skb since the original skb will not be modified before it is freed. This can make the performance better and save the memory.
Unified · Split
| @@ -276,7 +276,6 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) · 275 unmodified lines | ||
| 276 | 276 | { |
| 277 | 277 | struct rxe_pkt_info *pkt = SKB_TO_PKT(skb); |
| 278 | 278 | struct rxe_mc_grp *mcg; |
| 279 | − struct sk_buff *skb_copy; | |
| 280 | 279 | struct rxe_mc_elem *mce; |
| 281 | 280 | struct rxe_qp *qp; |
| 282 | 281 | union ib_gid dgid; |
| @@ -309,18 +308,14 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) · 26 unmodified lines | ||
| 309 | 308 | continue; |
| 310 | 309 | |
| 311 | 310 | /* if *not* the last qp in the list |
| 312 | − * make a copy of the skb to post to the next qp | |
| 311 | + * increase the users of the skb then post to the next qp | |
| 313 | 312 | */ |
| 314 | − skb_copy = (mce->qp_list.next != &mcg->qp_list) ? | |
| 315 | − skb_clone(skb, GFP_ATOMIC) : NULL; | |
| 313 | + if (mce->qp_list.next != &mcg->qp_list) | |
| 314 | + refcount_inc(&skb->users); | |
| 316 | 315 | |
| 317 | 316 | pkt->qp = qp; |
| 318 | 317 | rxe_add_ref(qp); |
| 319 | 318 | rxe_rcv_pkt(rxe, pkt, skb); |
| 320 | − | |
| 321 | − skb = skb_copy; | |
| 322 | − if (!skb) | |
| 323 | − break; | |
| 324 | 319 | } |
| 325 | 320 | |
| 326 | 321 | spin_unlock_bh(&mcg->mcg_lock); |
| @@ -328,8 +323,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) · 1 unmodified line | ||
| 328 | 323 | rxe_drop_ref(mcg); /* drop ref from rxe_pool_get_key. */ |
| 329 | 324 | |
| 330 | 325 | err1: |
| 331 | − if (skb) | |
| 332 | − kfree_skb(skb); | |
| 326 | + kfree_skb(skb); | |
| 333 | 327 | } |
| 334 | 328 | |
| 335 | 329 | static int rxe_match_dgid(struct rxe_dev *rxe, struct sk_buff *skb) |