]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sdp: RdmaRdCompl not sent sometimes
authorAmir Vadai <amirv@mellanox.co.il>
Tue, 14 Dec 2010 06:48:42 +0000 (08:48 +0200)
committerMukesh Kacker <mukesh.kacker@oracle.com>
Tue, 6 Oct 2015 12:05:36 +0000 (05:05 -0700)
When SrcAvailCancel is handled after RDMA finshed and before sending
RdmaRdCompl, RdmaRdCompl won't be sent, and a data corruption will occur.
Made sure that all sdp_abort_rx_srcavail will send RdmaRdCompl if needed.

Signed-off-by: Amir Vadai <amirv@mellanox.co.il>
drivers/infiniband/ulp/sdp/sdp.h
drivers/infiniband/ulp/sdp/sdp_main.c
drivers/infiniband/ulp/sdp/sdp_rx.c
drivers/infiniband/ulp/sdp/sdp_zcopy.c

index 2c967384adfd9d3aa1dcce9d9510b6f42321764c..5bce6caa1c6506d42e808cf09b04c87b8a0d191a 100644 (file)
@@ -259,6 +259,7 @@ struct rx_srcavail_state {
        /* Advertised buffer stuff */
        u32 mseq;
        u32 reported;
+       u32 copied;
        u32 len;
        u32 rkey;
        u64 vaddr;
@@ -909,6 +910,7 @@ void sdp_reset(struct sock *sk);
 int sdp_tx_wait_memory(struct sdp_sock *ssk, long *timeo_p, int *credits_needed);
 void sdp_skb_entail(struct sock *sk, struct sk_buff *skb);
 void sdp_start_cma_timewait_timeout(struct sdp_sock *ssk, int timeo);
+int sdp_abort_rx_srcavail(struct sock *sk);
 extern struct rw_semaphore device_removal_lock;
 
 /* sdp_proc.c */
@@ -945,10 +947,10 @@ void sdp_handle_sendsm(struct sdp_sock *ssk, u32 mseq_ack);
 void sdp_handle_rdma_read_compl(struct sdp_sock *ssk, u32 mseq_ack,
                u32 bytes_completed);
 int sdp_handle_rdma_read_cqe(struct sdp_sock *ssk);
-int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb,
-               unsigned long *used, u32 offset);
+int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, int msg_iovlen,
+               struct sk_buff *skb, unsigned long *used, u32 offset);
 int sdp_post_rdma_rd_compl(struct sock *sk,
-               struct rx_srcavail_state *rx_sa, u32 offset);
+               struct rx_srcavail_state *rx_sa);
 int sdp_post_sendsm(struct sock *sk);
 void sdp_abort_srcavail(struct sock *sk);
 void sdp_abort_rdma_read(struct sock *sk);
index 113946376b8796bf4a37c6dd3d4002ba7709639a..616fb72b5f4c27fa26a27e73d06efc96c9be0251 100644 (file)
@@ -125,8 +125,6 @@ spinlock_t sock_list_lock;
 
 DECLARE_RWSEM(device_removal_lock);
 
-static inline int sdp_abort_rx_srcavail(struct sock *sk);
-
 static inline unsigned int sdp_keepalive_time_when(const struct sdp_sock *ssk)
 {
        return ssk->keepalive_time ? : sdp_keepalive_time;
@@ -2169,7 +2167,7 @@ fin:
        return err;
 }
 
-static inline int sdp_abort_rx_srcavail(struct sock *sk)
+int sdp_abort_rx_srcavail(struct sock *sk)
 {
        struct sdp_sock *ssk = sdp_sk(sk);
        struct sdp_bsdh *h =
@@ -2179,6 +2177,11 @@ static inline int sdp_abort_rx_srcavail(struct sock *sk)
 
        h->mid = SDP_MID_DATA;
 
+       if (sdp_post_rdma_rd_compl(sk, ssk->rx_sa)) {
+               sdp_warn(sk, "Couldn't send RdmaRdComp - "
+                               "data corruption might occur\n");
+       }
+
        RX_SRCAVAIL_STATE(ssk->rx_sa->skb) = NULL;
        kfree(ssk->rx_sa);
        ssk->rx_sa = NULL;
@@ -2458,7 +2461,7 @@ sdp_mid_data:
                        if (rx_sa && offset >= skb->len) {
                                /* No more payload - start rdma copy */
                                sdp_dbg_data(sk, "RDMA copy of 0x%lx bytes\n", used);
-                               err = sdp_rdma_to_iovec(sk, msg->msg_iov, skb,
+                               err = sdp_rdma_to_iovec(sk, msg->msg_iov, msg->msg_iovlen, skb,
                                                &used, offset);
                                if (unlikely(err)) {
                                        /* ssk->rx_sa might had been freed when
@@ -2482,6 +2485,7 @@ sdp_mid_data:
                                                /* TODO: skip header? */
                                                msg->msg_iov, used);
                                if (rx_sa && !(flags & MSG_PEEK)) {
+                                       rx_sa->copied += used;
                                        rx_sa->reported += used;
                                }
                        }
@@ -2509,7 +2513,7 @@ skip_copy:
 
 
                if (rx_sa && !(flags & MSG_PEEK)) {
-                       rc = sdp_post_rdma_rd_compl(sk, rx_sa, offset);
+                       rc = sdp_post_rdma_rd_compl(sk, rx_sa);
                        if (unlikely(rc)) {
                                sdp_abort_rx_srcavail(sk);
                                rx_sa = NULL;
index 1bba5db535ecfb462f76f8d8c4a3a365065903a8..5de64928146ddd74e4e360fc8ef95ed95bac8804 100644 (file)
@@ -503,10 +503,7 @@ static int sdp_process_rx_ctl_skb(struct sdp_sock *ssk, struct sk_buff *skb)
        case SDP_MID_SRCAVAIL_CANCEL:
                if (ssk->rx_sa && after(ntohl(h->mseq), ssk->rx_sa->mseq) &&
                                !ssk->tx_ring.rdma_inflight) {
-                       sdp_dbg(sk, "Handling SrcAvailCancel - post SendSM\n");
-                       RX_SRCAVAIL_STATE(ssk->rx_sa->skb) = NULL;
-                       kfree(ssk->rx_sa);
-                       ssk->rx_sa = NULL;
+                       sdp_abort_rx_srcavail(sk);
                        sdp_post_sendsm(sk);
                }
                break;
index df8607d8cd6c99141c58cd5b0805f2846a65ce01..b80e52c19bc4920addc328ba9c9f7589d3c810b1 100644 (file)
@@ -274,22 +274,21 @@ static int sdp_wait_rdma_wr_finished(struct sdp_sock *ssk)
        return rc;
 }
 
-int sdp_post_rdma_rd_compl(struct sock *sk,
-               struct rx_srcavail_state *rx_sa, u32 offset)
+int sdp_post_rdma_rd_compl(struct sock *sk, struct rx_srcavail_state *rx_sa)
 {
        struct sk_buff *skb;
-       int copied = offset - rx_sa->reported;
+       int unreported = rx_sa->copied - rx_sa->reported;
 
-       if (offset <= rx_sa->reported)
+       if (rx_sa->copied <= rx_sa->reported)
                return 0;
 
-       skb = sdp_alloc_skb_rdmardcompl(sk, copied, 0);
+       skb = sdp_alloc_skb_rdmardcompl(sk, unreported, 0);
        if (unlikely(!skb))
                return -ENOMEM;
 
        sdp_skb_entail(sk, skb);
 
-       rx_sa->reported += copied;
+       rx_sa->reported += unreported;
 
        sdp_post_sends(sdp_sk(sk), 0);
 
@@ -561,20 +560,24 @@ static int sdp_post_rdma_read(struct sock *sk, struct rx_srcavail_state *rx_sa,
        return rc;
 }
 
-int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb,
-               unsigned long *used, u32 offset)
+int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, int msg_iovlen,
+               struct sk_buff *skb, unsigned long *used, u32 offset)
 {
        struct sdp_sock *ssk = sdp_sk(sk);
        struct rx_srcavail_state *rx_sa = RX_SRCAVAIL_STATE(skb);
        int rc = 0;
        int len = *used;
        int copied;
+       int i = 0;
 
        if (unlikely(!ssk->ib_device))
                return -ENODEV;
 
-       while (!iov->iov_len)
+       while (!iov->iov_len) {
                ++iov;
+               i++;
+       }
+       WARN_ON(i >= msg_iovlen);
 
        sdp_dbg_data(sk_ssk(ssk), "preparing RDMA read."
                " len: 0x%x. buffer len: 0x%zx\n", len, iov->iov_len);
@@ -613,6 +616,7 @@ int sdp_rdma_to_iovec(struct sock *sk, struct iovec *iov, struct sk_buff *skb,
        sdp_update_iov_used(sk, iov, copied);
        atomic_add(copied, &ssk->rcv_nxt);
        *used = copied;
+       rx_sa->copied += copied;
 
 err_wait:
        ssk->tx_ring.rdma_inflight = NULL;