|
|
@@ -115,9 +115,12 @@ isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id,
|
|
|
attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS;
|
|
|
/*
|
|
|
* FIXME: Use devattr.max_sge - 2 for max_send_sge as
|
|
|
- * work-around for RDMA_READ..
|
|
|
+ * work-around for RDMA_READs with ConnectX-2.
|
|
|
+ *
|
|
|
+ * Also, still make sure to have at least two SGEs for
|
|
|
+ * outgoing control PDU responses.
|
|
|
*/
|
|
|
- attr.cap.max_send_sge = device->dev_attr.max_sge - 2;
|
|
|
+ attr.cap.max_send_sge = max(2, device->dev_attr.max_sge - 2);
|
|
|
isert_conn->max_sge = attr.cap.max_send_sge;
|
|
|
|
|
|
attr.cap.max_recv_sge = 1;
|
|
|
@@ -225,12 +228,16 @@ isert_create_device_ib_res(struct isert_device *device)
|
|
|
struct isert_cq_desc *cq_desc;
|
|
|
struct ib_device_attr *dev_attr;
|
|
|
int ret = 0, i, j;
|
|
|
+ int max_rx_cqe, max_tx_cqe;
|
|
|
|
|
|
dev_attr = &device->dev_attr;
|
|
|
ret = isert_query_device(ib_dev, dev_attr);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
+ max_rx_cqe = min(ISER_MAX_RX_CQ_LEN, dev_attr->max_cqe);
|
|
|
+ max_tx_cqe = min(ISER_MAX_TX_CQ_LEN, dev_attr->max_cqe);
|
|
|
+
|
|
|
/* asign function handlers */
|
|
|
if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS &&
|
|
|
dev_attr->device_cap_flags & IB_DEVICE_SIGNATURE_HANDOVER) {
|
|
|
@@ -272,7 +279,7 @@ isert_create_device_ib_res(struct isert_device *device)
|
|
|
isert_cq_rx_callback,
|
|
|
isert_cq_event_callback,
|
|
|
(void *)&cq_desc[i],
|
|
|
- ISER_MAX_RX_CQ_LEN, i);
|
|
|
+ max_rx_cqe, i);
|
|
|
if (IS_ERR(device->dev_rx_cq[i])) {
|
|
|
ret = PTR_ERR(device->dev_rx_cq[i]);
|
|
|
device->dev_rx_cq[i] = NULL;
|
|
|
@@ -284,7 +291,7 @@ isert_create_device_ib_res(struct isert_device *device)
|
|
|
isert_cq_tx_callback,
|
|
|
isert_cq_event_callback,
|
|
|
(void *)&cq_desc[i],
|
|
|
- ISER_MAX_TX_CQ_LEN, i);
|
|
|
+ max_tx_cqe, i);
|
|
|
if (IS_ERR(device->dev_tx_cq[i])) {
|
|
|
ret = PTR_ERR(device->dev_tx_cq[i]);
|
|
|
device->dev_tx_cq[i] = NULL;
|
|
|
@@ -803,14 +810,25 @@ isert_disconnect_work(struct work_struct *work)
|
|
|
complete(&isert_conn->conn_wait);
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
+static int
|
|
|
isert_disconnected_handler(struct rdma_cm_id *cma_id, bool disconnect)
|
|
|
{
|
|
|
- struct isert_conn *isert_conn = (struct isert_conn *)cma_id->context;
|
|
|
+ struct isert_conn *isert_conn;
|
|
|
+
|
|
|
+ if (!cma_id->qp) {
|
|
|
+ struct isert_np *isert_np = cma_id->context;
|
|
|
+
|
|
|
+ isert_np->np_cm_id = NULL;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ isert_conn = (struct isert_conn *)cma_id->context;
|
|
|
|
|
|
isert_conn->disconnect = disconnect;
|
|
|
INIT_WORK(&isert_conn->conn_logout_work, isert_disconnect_work);
|
|
|
schedule_work(&isert_conn->conn_logout_work);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
@@ -825,6 +843,9 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
|
|
switch (event->event) {
|
|
|
case RDMA_CM_EVENT_CONNECT_REQUEST:
|
|
|
ret = isert_connect_request(cma_id, event);
|
|
|
+ if (ret)
|
|
|
+ pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
|
|
|
+ event->event, ret);
|
|
|
break;
|
|
|
case RDMA_CM_EVENT_ESTABLISHED:
|
|
|
isert_connected_handler(cma_id);
|
|
|
@@ -834,7 +855,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
|
|
case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */
|
|
|
disconnect = true;
|
|
|
case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */
|
|
|
- isert_disconnected_handler(cma_id, disconnect);
|
|
|
+ ret = isert_disconnected_handler(cma_id, disconnect);
|
|
|
break;
|
|
|
case RDMA_CM_EVENT_CONNECT_ERROR:
|
|
|
default:
|
|
|
@@ -842,12 +863,6 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (ret != 0) {
|
|
|
- pr_err("isert_cma_handler failed RDMA_CM_EVENT: 0x%08x %d\n",
|
|
|
- event->event, ret);
|
|
|
- dump_stack();
|
|
|
- }
|
|
|
-
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
@@ -3190,7 +3205,8 @@ isert_free_np(struct iscsi_np *np)
|
|
|
{
|
|
|
struct isert_np *isert_np = (struct isert_np *)np->np_context;
|
|
|
|
|
|
- rdma_destroy_id(isert_np->np_cm_id);
|
|
|
+ if (isert_np->np_cm_id)
|
|
|
+ rdma_destroy_id(isert_np->np_cm_id);
|
|
|
|
|
|
np->np_context = NULL;
|
|
|
kfree(isert_np);
|