aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTom Tucker <tom@opengridcomputing.com>2008-05-01 12:13:50 -0400
committerTom Tucker <tom@opengridcomputing.com>2008-05-19 08:33:56 -0400
commit1711386c62c97f7fb086a2247d44cdb1f8867640 (patch)
tree4f4f70ada8683fe1e8884493469355acd2633790 /net
parent0905c0f0a2346516ecd12f0a4f33dca571b0dccd (diff)
svcrdma: Move the QP and cm_id destruction to svc_rdma_free
Move the destruction of the QP and CM_ID to the free path so that the QP cleanup code doesn't race with the dto_tasklet handling flushed WR. The QP reference is not needed because we now have a reference for every WR. Also add a guard in the SQ and RQ completion handlers to ignore calls generated by some providers when the QP is destroyed. Signed-off-by: Tom Tucker <tom@opengridcomputing.com>
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 31b1927b5ee6..b412a49c46fc 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -252,11 +252,15 @@ static void rq_comp_handler(struct ib_cq *cq, void *cq_context)
252 struct svcxprt_rdma *xprt = cq_context; 252 struct svcxprt_rdma *xprt = cq_context;
253 unsigned long flags; 253 unsigned long flags;
254 254
255 /* Guard against unconditional flush call for destroyed QP */
256 if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
257 return;
258
255 /* 259 /*
256 * Set the bit regardless of whether or not it's on the list 260 * Set the bit regardless of whether or not it's on the list
257 * because it may be on the list already due to an SQ 261 * because it may be on the list already due to an SQ
258 * completion. 262 * completion.
259 */ 263 */
260 set_bit(RDMAXPRT_RQ_PENDING, &xprt->sc_flags); 264 set_bit(RDMAXPRT_RQ_PENDING, &xprt->sc_flags);
261 265
262 /* 266 /*
@@ -393,11 +397,15 @@ static void sq_comp_handler(struct ib_cq *cq, void *cq_context)
393 struct svcxprt_rdma *xprt = cq_context; 397 struct svcxprt_rdma *xprt = cq_context;
394 unsigned long flags; 398 unsigned long flags;
395 399
400 /* Guard against unconditional flush call for destroyed QP */
401 if (atomic_read(&xprt->sc_xprt.xpt_ref.refcount)==0)
402 return;
403
396 /* 404 /*
397 * Set the bit regardless of whether or not it's on the list 405 * Set the bit regardless of whether or not it's on the list
398 * because it may be on the list already due to an RQ 406 * because it may be on the list already due to an RQ
399 * completion. 407 * completion.
400 */ 408 */
401 set_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags); 409 set_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags);
402 410
403 /* 411 /*
@@ -852,7 +860,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
852 newxprt->sc_sq_depth = qp_attr.cap.max_send_wr; 860 newxprt->sc_sq_depth = qp_attr.cap.max_send_wr;
853 newxprt->sc_max_requests = qp_attr.cap.max_recv_wr; 861 newxprt->sc_max_requests = qp_attr.cap.max_recv_wr;
854 } 862 }
855 svc_xprt_get(&newxprt->sc_xprt);
856 newxprt->sc_qp = newxprt->sc_cm_id->qp; 863 newxprt->sc_qp = newxprt->sc_cm_id->qp;
857 864
858 /* Register all of physical memory */ 865 /* Register all of physical memory */
@@ -926,10 +933,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
926 dprintk("svcrdma: failure accepting new connection rc=%d.\n", ret); 933 dprintk("svcrdma: failure accepting new connection rc=%d.\n", ret);
927 /* Take a reference in case the DTO handler runs */ 934 /* Take a reference in case the DTO handler runs */
928 svc_xprt_get(&newxprt->sc_xprt); 935 svc_xprt_get(&newxprt->sc_xprt);
929 if (newxprt->sc_qp && !IS_ERR(newxprt->sc_qp)) { 936 if (newxprt->sc_qp && !IS_ERR(newxprt->sc_qp))
930 ib_destroy_qp(newxprt->sc_qp); 937 ib_destroy_qp(newxprt->sc_qp);
931 svc_xprt_put(&newxprt->sc_xprt);
932 }
933 rdma_destroy_id(newxprt->sc_cm_id); 938 rdma_destroy_id(newxprt->sc_cm_id);
934 /* This call to put will destroy the transport */ 939 /* This call to put will destroy the transport */
935 svc_xprt_put(&newxprt->sc_xprt); 940 svc_xprt_put(&newxprt->sc_xprt);
@@ -941,10 +946,7 @@ static void svc_rdma_release_rqst(struct svc_rqst *rqstp)
941} 946}
942 947
943/* 948/*
944 * When connected, an svc_xprt has at least three references: 949 * When connected, an svc_xprt has at least two references:
945 *
946 * - A reference held by the QP. We still hold that here because this
947 * code deletes the QP and puts the reference.
948 * 950 *
949 * - A reference held by the cm_id between the ESTABLISHED and 951 * - A reference held by the cm_id between the ESTABLISHED and
950 * DISCONNECTED events. If the remote peer disconnected first, this 952 * DISCONNECTED events. If the remote peer disconnected first, this
@@ -953,7 +955,7 @@ static void svc_rdma_release_rqst(struct svc_rqst *rqstp)
953 * - A reference held by the svc_recv code that called this function 955 * - A reference held by the svc_recv code that called this function
954 * as part of close processing. 956 * as part of close processing.
955 * 957 *
956 * At a minimum two references should still be held. 958 * At a minimum one references should still be held.
957 */ 959 */
958static void svc_rdma_detach(struct svc_xprt *xprt) 960static void svc_rdma_detach(struct svc_xprt *xprt)
959{ 961{
@@ -963,15 +965,6 @@ static void svc_rdma_detach(struct svc_xprt *xprt)
963 965
964 /* Disconnect and flush posted WQE */ 966 /* Disconnect and flush posted WQE */
965 rdma_disconnect(rdma->sc_cm_id); 967 rdma_disconnect(rdma->sc_cm_id);
966
967 /* Destroy the QP if present (not a listener) */
968 if (rdma->sc_qp && !IS_ERR(rdma->sc_qp)) {
969 ib_destroy_qp(rdma->sc_qp);
970 svc_xprt_put(xprt);
971 }
972
973 /* Destroy the CM ID */
974 rdma_destroy_id(rdma->sc_cm_id);
975} 968}
976 969
977static void __svc_rdma_free(struct work_struct *work) 970static void __svc_rdma_free(struct work_struct *work)
@@ -983,6 +976,13 @@ static void __svc_rdma_free(struct work_struct *work)
983 /* We should only be called from kref_put */ 976 /* We should only be called from kref_put */
984 BUG_ON(atomic_read(&rdma->sc_xprt.xpt_ref.refcount) != 0); 977 BUG_ON(atomic_read(&rdma->sc_xprt.xpt_ref.refcount) != 0);
985 978
979 /* Destroy the QP if present (not a listener) */
980 if (rdma->sc_qp && !IS_ERR(rdma->sc_qp))
981 ib_destroy_qp(rdma->sc_qp);
982
983 /* Destroy the CM ID */
984 rdma_destroy_id(rdma->sc_cm_id);
985
986 if (rdma->sc_sq_cq && !IS_ERR(rdma->sc_sq_cq)) 986 if (rdma->sc_sq_cq && !IS_ERR(rdma->sc_sq_cq))
987 ib_destroy_cq(rdma->sc_sq_cq); 987 ib_destroy_cq(rdma->sc_sq_cq);
988 988