[PATCH 6/6] nvme/rdma: Make nvme_rdma_conn_rejected() more informative

Bart Van Assche bart.vanassche at sandisk.com
Thu Oct 20 10:34:16 PDT 2016


On 10/20/2016 07:35 AM, Steve Wise wrote:
> iWARP RDMA_CM_EVENT_REJECTED events have a -errno as the event status.  Perhaps
> you could at the very least dump the error as an integer here?  But an  errno
> string would be ideal. :)

Hello Steve,

Is something like the patch below perhaps what you had in mind? While I was
preparing this patch I was disappointed to see that another implementation
is needed for IB/RoCE transports compared to iWARP transports.

Thanks,

Bart.


[PATCH] nvme/rdma: Provide more information about rejected connection attempts

While I was figuring out how to make the nvme-rdma driver log in to
the nvmet-rdma driver over an IB network, the following message
appeared in the system log:

    nvme nvme0: Connect rejected, status 0.

That message is not very helpful. Hence this patch that makes the
messages reported by nvme_rdma_conn_rejected() more informative.

---
 drivers/nvme/host/rdma.c | 79 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 69 insertions(+), 10 deletions(-)

diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 8a80a04..c1b9fd6 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1206,24 +1206,82 @@ static int nvme_rdma_conn_established(struct nvme_rdma_queue *queue)
 	return ret;
 }
 
-static int nvme_rdma_conn_rejected(struct nvme_rdma_queue *queue,
-		struct rdma_cm_event *ev)
+static int nvme_rdma_ib_conn_rejected(struct nvme_rdma_queue *queue,
+		const struct rdma_cm_event *ev)
+{
+	char reason[32];
+
+	switch (ev->status) {
+	case IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID:
+		strlcpy(reason, "duplicate local comm id", sizeof(reason));
+		break;
+	case IB_CM_REJ_CONSUMER_DEFINED:
+		if (ev->param.conn.private_data_len) {
+			const struct nvme_rdma_cm_rej *rej =
+				ev->param.conn.private_data;
+
+			snprintf(reason, sizeof(reason),
+				 "NVMe RDMA CM status %d",
+				 le16_to_cpu(rej->sts));
+			/* XXX: Think of something clever to do here... */
+		} else {
+			strlcpy(reason, "no private data", sizeof(reason));
+		}
+		break;
+	case IB_CM_REJ_INVALID_SERVICE_ID:
+		strlcpy(reason, "invalid service ID", sizeof(reason));
+		break;
+	case IB_CM_REJ_STALE_CONN:
+		strlcpy(reason, "stale connection", sizeof(reason));
+		break;
+	default:
+		snprintf(reason, sizeof(reason), "REJ reason %#x", ev->status);
+		break;
+	}
+
+	dev_err(queue->ctrl->ctrl.device, "Connect rejected, %s.\n", reason);
+
+	return -ECONNRESET;
+}
+
+static int nvme_rdma_iw_conn_rejected(struct nvme_rdma_queue *queue,
+		const struct rdma_cm_event *ev)
 {
+	char reason[32];
+
 	if (ev->param.conn.private_data_len) {
-		struct nvme_rdma_cm_rej *rej =
-			(struct nvme_rdma_cm_rej *)ev->param.conn.private_data;
+		const struct nvme_rdma_cm_rej *rej =
+			ev->param.conn.private_data;
 
-		dev_err(queue->ctrl->ctrl.device,
-			"Connect rejected, status %d.", le16_to_cpu(rej->sts));
-		/* XXX: Think of something clever to do here... */
+		snprintf(reason, sizeof(reason),
+			 "NVMe RDMA CM status %d",
+			 le16_to_cpu(rej->sts));
+			/* XXX: Think of something clever to do here... */
 	} else {
-		dev_err(queue->ctrl->ctrl.device,
-			"Connect rejected, no private data.\n");
+		strlcpy(reason, "no private data", sizeof(reason));
 	}
 
+	dev_err(queue->ctrl->ctrl.device, "Connect rejected, errno %d, %s.\n",
+		ev->status, reason);
+
 	return -ECONNRESET;
 }
 
+static int nvme_rdma_conn_rejected(struct nvme_rdma_queue *queue,
+		enum rdma_transport_type tt,
+		const struct rdma_cm_event *ev)
+{
+	switch (tt) {
+	case RDMA_TRANSPORT_IB:
+		return nvme_rdma_ib_conn_rejected(queue, ev);
+	case RDMA_TRANSPORT_IWARP:
+		return nvme_rdma_iw_conn_rejected(queue, ev);
+	default:
+		WARN_ON_ONCE(true);
+		return -ECONNRESET;
+	}
+}
+
 static int nvme_rdma_addr_resolved(struct nvme_rdma_queue *queue)
 {
 	struct nvme_rdma_device *dev;
@@ -1331,7 +1389,8 @@ static int nvme_rdma_cm_handler(struct rdma_cm_id *cm_id,
 		complete(&queue->cm_done);
 		return 0;
 	case RDMA_CM_EVENT_REJECTED:
-		cm_error = nvme_rdma_conn_rejected(queue, ev);
+		cm_error = nvme_rdma_conn_rejected(queue,
+				cm_id->route.addr.dev_addr.transport, ev);
 		break;
 	case RDMA_CM_EVENT_ADDR_ERROR:
 	case RDMA_CM_EVENT_ROUTE_ERROR:
-- 
2.10.1






More information about the Linux-nvme mailing list