From 5ce18125c34b998b7d33407b6a72d18038351fb4 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 2 Aug 2006 10:05:59 +0300 Subject: [PATCH] IB/sdp: Two bugfixes in SDP 1. Do not mark socket as closed on flushed with error events 2. Simplify locking and reduce code duplication for poll code Signed-off-by: Michael S. Tsirkin --- drivers/infiniband/ulp/sdp/sdp.h | 1 + drivers/infiniband/ulp/sdp/sdp_bcopy.c | 63 ++++++++++++++------------ drivers/infiniband/ulp/sdp/sdp_cma.c | 1 + drivers/infiniband/ulp/sdp/sdp_main.c | 12 ++--- 4 files changed, 42 insertions(+), 35 deletions(-) diff --git a/drivers/infiniband/ulp/sdp/sdp.h b/drivers/infiniband/ulp/sdp/sdp.h index 39e462859e2c..0c61658d7c6b 100644 --- a/drivers/infiniband/ulp/sdp/sdp.h +++ b/drivers/infiniband/ulp/sdp/sdp.h @@ -168,6 +168,7 @@ void sdp_completion_handler(struct ib_cq *cq, void *cq_context); void sdp_work(void *); void sdp_post_send(struct sdp_sock *ssk, struct sk_buff *skb, u8 mid); void sdp_post_recvs(struct sdp_sock *ssk); +void sdp_poll_cq(struct sdp_sock *ssk, struct ib_cq *cq); void sdp_post_sends(struct sdp_sock *ssk, int nonagle); void sdp_destroy_work(void *data); void sdp_time_wait_work(void *data); diff --git a/drivers/infiniband/ulp/sdp/sdp_bcopy.c b/drivers/infiniband/ulp/sdp/sdp_bcopy.c index f95ab03f537a..d46cad980f81 100644 --- a/drivers/infiniband/ulp/sdp/sdp_bcopy.c +++ b/drivers/infiniband/ulp/sdp/sdp_bcopy.c @@ -369,13 +369,14 @@ static void sdp_handle_wc(struct sdp_sock *ssk, struct ib_wc *wc) return; if (unlikely(wc->status)) { - if (wc->status != IB_WC_WR_FLUSH_ERR) + if (wc->status != IB_WC_WR_FLUSH_ERR) { sdp_dbg(&ssk->isk.sk, - "Recv completion with error. " - "Status %d\n", wc->status); + "Recv completion with error. " + "Status %d\n", wc->status); + sdp_set_error(&ssk->isk.sk, -ECONNRESET); + wake_up(&ssk->wq); + } __kfree_skb(skb); - sdp_set_error(&ssk->isk.sk, -ECONNRESET); - wake_up(&ssk->wq); } else { /* TODO: handle msg < bsdh */ sdp_dbg_data(&ssk->isk.sk, @@ -428,12 +429,13 @@ static void sdp_handle_wc(struct sdp_sock *ssk, struct ib_wc *wc) return; sk_stream_free_skb(&ssk->isk.sk, skb); if (unlikely(wc->status)) { - if (wc->status != IB_WC_WR_FLUSH_ERR) + if (wc->status != IB_WC_WR_FLUSH_ERR) { sdp_dbg(&ssk->isk.sk, - "Send completion with error. " - "Status %d\n", wc->status); - sdp_set_error(&ssk->isk.sk, -ECONNRESET); - wake_up(&ssk->wq); + "Send completion with error. " + "Status %d\n", wc->status); + sdp_set_error(&ssk->isk.sk, -ECONNRESET); + wake_up(&ssk->wq); + } } sk_stream_write_space(&ssk->isk.sk); @@ -461,35 +463,38 @@ void sdp_completion_handler(struct ib_cq *cq, void *cq_context) schedule_work(&ssk->work); } +void sdp_poll_cq(struct sdp_sock *ssk, struct ib_cq *cq) +{ + int n, i; + do { + n = ib_poll_cq(cq, SDP_NUM_WC, ssk->ibwc); + for (i = 0; i < n; ++i) { + sdp_handle_wc(ssk, ssk->ibwc + i); + } + } while (n == SDP_NUM_WC); +} + void sdp_work(void *data) { struct sock *sk = (struct sock *)data; struct sdp_sock *ssk = sdp_sk(sk); struct ib_cq *cq; - int n, i; sdp_dbg_data(sk, "%s\n", __func__); + lock_sock(sk); cq = ssk->cq; if (unlikely(!cq)) - return; - - do { - lock_sock(sk); - n = ib_poll_cq(cq, SDP_NUM_WC, ssk->ibwc); - for (i = 0; i < n; ++i) { - sdp_handle_wc(ssk, ssk->ibwc + i); - } - release_sock(sk); - } while (n == SDP_NUM_WC); + goto out; + sdp_poll_cq(ssk, cq); + release_sock(sk); sk_stream_mem_reclaim(sk); + lock_sock(sk); + cq = ssk->cq; + if (unlikely(!cq)) + goto out; ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); - do { - lock_sock(sk); - n = ib_poll_cq(cq, SDP_NUM_WC, ssk->ibwc); - for (i = 0; i < n; ++i) { - sdp_handle_wc(ssk, ssk->ibwc + i); - } - release_sock(sk); - } while (n == SDP_NUM_WC); + sdp_poll_cq(ssk, cq); +out: + release_sock(sk); } diff --git a/drivers/infiniband/ulp/sdp/sdp_cma.c b/drivers/infiniband/ulp/sdp/sdp_cma.c index cf8d848877d4..527f86bf98c4 100644 --- a/drivers/infiniband/ulp/sdp/sdp_cma.c +++ b/drivers/infiniband/ulp/sdp/sdp_cma.c @@ -482,6 +482,7 @@ int sdp_cma_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) done: release_sock(parent); sk_common_release(child); + } else if (rc) { } return rc; } diff --git a/drivers/infiniband/ulp/sdp/sdp_main.c b/drivers/infiniband/ulp/sdp/sdp_main.c index 41a2a3dca0e8..4e3b1b5c6b61 100644 --- a/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/drivers/infiniband/ulp/sdp/sdp_main.c @@ -148,14 +148,13 @@ void sdp_close_sk(struct sock *sk) ssk->id = NULL; release_sock(sk); rdma_destroy_id(id); - } else - release_sock(sk); + lock_sock(sk); + } if (ssk->qp) { pd = ssk->qp->pd; cq = ssk->cq; sdp_sk(sk)->cq = NULL; - flush_scheduled_work(); ib_destroy_qp(ssk->qp); while (ssk->rx_head != ssk->rx_tail) { @@ -174,10 +173,8 @@ void sdp_close_sk(struct sock *sk) } } - if (cq) { + if (cq) ib_destroy_cq(cq); - flush_scheduled_work(); - } if (ssk->mr) ib_dereg_mr(ssk->mr); @@ -191,6 +188,9 @@ void sdp_close_sk(struct sock *sk) kfree(sdp_sk(sk)->tx_ring); sdp_dbg(sk, "%s done; releasing sock\n", __func__); + release_sock(sk); + + flush_scheduled_work(); } static void sdp_destruct(struct sock *sk) -- 2.50.1