From 5908a73f975c271f53e8539b2429cc1cdafd8184 Mon Sep 17 00:00:00 2001 From: Mohammed Rafi KC Date: Thu, 30 Oct 2014 10:35:57 +0530 Subject: rdma:client process will hang if server is started to send the request before completing connection establishment Backport of http://review.gluster.org/9003 in rdma, client and server will interchange their available buffers during the handshake to post incoming messages. Initially the available buffer is set to one, for the first message during handshake,when first message is received, quota for the buffer will set to proper value. So before receiving the message if server started to send the message, then the reserverd buffer for handshake will be utilised, then the handshake will fail because of lack of buffers. So we should block sending messages by server before proper connection establishment. Change-Id: I1797ae8a25163864c338641d74cd4eef6fb34bb5 BUG: 1166515 Signed-off-by: Mohammed Rafi KC Reviewed-on: http://review.gluster.org/9003 Tested-by: Gluster Build System Reviewed-by: Raghavendra G Tested-by: Raghavendra G Reviewed-on: http://review.gluster.org/9178 Reviewed-by: Raghavendra Bhat --- rpc/rpc-transport/rdma/src/rdma.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'rpc') diff --git a/rpc/rpc-transport/rdma/src/rdma.c b/rpc/rpc-transport/rdma/src/rdma.c index 1e0cce54b7a..a1c86228ae6 100644 --- a/rpc/rpc-transport/rdma/src/rdma.c +++ b/rpc/rpc-transport/rdma/src/rdma.c @@ -2696,13 +2696,34 @@ gf_rdma_submit_request (rpc_transport_t *this, rpc_transport_req_t *req) int32_t ret = 0; gf_rdma_ioq_t *entry = NULL; rpc_transport_data_t data = {0, }; + gf_rdma_private_t *priv = NULL; + gf_rdma_peer_t *peer = NULL; if (req == NULL) { goto out; } + priv = this->private; + if (priv == NULL) { + ret = -1; + goto out; + } + + peer = &priv->peer; data.is_request = 1; data.data.req = *req; +/* + * when fist message is received on a transport, quota variable will + * initiaize and quota_set will set to one. In gluster code client + * process with respect to transport is the one who sends the first + * message. Before settng quota_set variable if a submit request is + * came on server, then the message should not send. + */ + + if (priv->entity == GF_RDMA_SERVER && peer->quota_set == 0) { + ret = 0; + goto out; + } entry = gf_rdma_ioq_new (this, &data); if (entry == NULL) { -- cgit