diff options
| -rw-r--r-- | net/sunrpc/xprtrdma/svc_rdma_transport.c | 40 |
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 | */ |
| 958 | static void svc_rdma_detach(struct svc_xprt *xprt) | 960 | static 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 | ||
| 977 | static void __svc_rdma_free(struct work_struct *work) | 970 | static 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 | ||
