]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
IB/rxe: avoid double kfree_skb
authorZhu Yanjun <yanjun.zhu@oracle.com>
Thu, 26 Apr 2018 04:41:10 +0000 (00:41 -0400)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Oct 2018 12:56:03 +0000 (14:56 +0200)
BugLink: http://bugs.launchpad.net/bugs/1794889
[ Upstream commit 9fd4350ba8953804f05215999e11a6cfb7b41f2b ]

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>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/infiniband/sw/rxe/rxe_req.c
drivers/infiniband/sw/rxe/rxe_resp.c

index 7bdaf71b82213bea1cf66f606d5e517706d2647c..785199990457068f614de7a71678845425ee34d3 100644 (file)
@@ -728,7 +728,6 @@ next_wqe:
                rollback_state(wqe, qp, &rollback_wqe, rollback_psn);
 
                if (ret == -EAGAIN) {
-                       kfree_skb(skb);
                        rxe_run_task(&qp->req.task, 1);
                        goto exit;
                }
index 01f926fd90296e7bbbfcf9da191299bcf39e5146..bd43c1c7a42fdb3938d04b8bfefa7fcd63550942 100644 (file)
@@ -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;
        }
 
@@ -955,10 +954,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;
@@ -1151,7 +1148,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;
                        }