mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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
					
				
					 2 changed files with 1 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -728,7 +728,6 @@ int rxe_requester(void *arg)
 | 
			
		|||
		rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
 | 
			
		||||
 | 
			
		||||
		if (ret == -EAGAIN) {
 | 
			
		||||
			kfree_skb(skb);
 | 
			
		||||
			rxe_run_task(&qp->req.task, 1);
 | 
			
		||||
			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);
 | 
			
		||||
	if (err) {
 | 
			
		||||
		pr_err("Failed sending RDMA reply.\n");
 | 
			
		||||
		kfree_skb(skb);
 | 
			
		||||
		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);
 | 
			
		||||
	if (err) {
 | 
			
		||||
	if (err)
 | 
			
		||||
		pr_err_ratelimited("Failed sending ack\n");
 | 
			
		||||
		kfree_skb(skb);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
err1:
 | 
			
		||||
	return err;
 | 
			
		||||
| 
						 | 
				
			
			@ -1141,7 +1138,6 @@ static enum resp_states duplicate_request(struct rxe_qp *qp,
 | 
			
		|||
			if (rc) {
 | 
			
		||||
				pr_err("Failed resending result. This flow is not handled - skb ignored\n");
 | 
			
		||||
				rxe_drop_ref(qp);
 | 
			
		||||
				kfree_skb(skb_copy);
 | 
			
		||||
				rc = RESPST_CLEANUP;
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue