IB/rxe: avoid double kfree_skb
When skb is sent, it will pass the following functions in soft roce.
rxe_send [rdma_rxe]
    ip_local_out
        __ip_local_out
        ip_output
            ip_finish_output
                ip_finish_output2
                    dev_queue_xmit
                        __dev_queue_xmit
                            dev_hard_start_xmit
In the above functions, if error occurs in the above functions or
iptables rules drop skb after ip_local_out, kfree_skb will be called.
So it is not necessary to call kfree_skb in soft roce module again.
Or else crash will occur.
The steps to reproduce:
     server                       client
    ---------                    ---------
    |1.1.1.1|<----rxe-channel--->|1.1.1.2|
    ---------                    ---------
On server: rping -s -a 1.1.1.1 -v -C 10000 -S 512
On client: rping -c -a 1.1.1.1 -v -C 10000 -S 512
The kernel configs CONFIG_DEBUG_KMEMLEAK and
CONFIG_DEBUG_OBJECTS are enabled on both server and client.
When rping runs, run the following command in server:
iptables -I OUTPUT -p udp  --dport 4791 -j DROP
Without this patch, crash will occur.
CC: Srinivas Eeda <srinivas.eeda@oracle.com>
CC: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									2da36d44a9
								
							
						
					
					
						commit
						9fd4350ba8
					
				| @ -728,7 +728,6 @@ next_wqe: | |||||||
| 		rollback_state(wqe, qp, &rollback_wqe, rollback_psn); | 		rollback_state(wqe, qp, &rollback_wqe, rollback_psn); | ||||||
| 
 | 
 | ||||||
| 		if (ret == -EAGAIN) { | 		if (ret == -EAGAIN) { | ||||||
| 			kfree_skb(skb); |  | ||||||
| 			rxe_run_task(&qp->req.task, 1); | 			rxe_run_task(&qp->req.task, 1); | ||||||
| 			goto exit; | 			goto exit; | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -742,7 +742,6 @@ static enum resp_states read_reply(struct rxe_qp *qp, | |||||||
| 	err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | 	err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | ||||||
| 	if (err) { | 	if (err) { | ||||||
| 		pr_err("Failed sending RDMA reply.\n"); | 		pr_err("Failed sending RDMA reply.\n"); | ||||||
| 		kfree_skb(skb); |  | ||||||
| 		return RESPST_ERR_RNR; | 		return RESPST_ERR_RNR; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -954,10 +953,8 @@ static int send_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | 	err = rxe_xmit_packet(rxe, qp, &ack_pkt, skb); | ||||||
| 	if (err) { | 	if (err) | ||||||
| 		pr_err_ratelimited("Failed sending ack\n"); | 		pr_err_ratelimited("Failed sending ack\n"); | ||||||
| 		kfree_skb(skb); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| err1: | err1: | ||||||
| 	return err; | 	return err; | ||||||
| @ -1141,7 +1138,6 @@ static enum resp_states duplicate_request(struct rxe_qp *qp, | |||||||
| 			if (rc) { | 			if (rc) { | ||||||
| 				pr_err("Failed resending result. This flow is not handled - skb ignored\n"); | 				pr_err("Failed resending result. This flow is not handled - skb ignored\n"); | ||||||
| 				rxe_drop_ref(qp); | 				rxe_drop_ref(qp); | ||||||
| 				kfree_skb(skb_copy); |  | ||||||
| 				rc = RESPST_CLEANUP; | 				rc = RESPST_CLEANUP; | ||||||
| 				goto out; | 				goto out; | ||||||
| 			} | 			} | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user