The np listener cm_id will also get ADDR_CHANGE event upcall (in case it is bound to a specific IP). Handle it correctly by creating a new cm_id and implicitly destroy the old one. Since this is the second event a listener np cm_id may encounter, we move the np cm_id event handling to a routine. Reported-by: Slava Shwartsman <valyushash@xxxxxxxxx> Signed-off-by: Sagi Grimberg <sagig@xxxxxxxxxxxx> --- drivers/infiniband/ulp/isert/ib_isert.c | 38 ++++++++++++++++++++++++------ 1 files changed, 30 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 5b883aa..c4379d1 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -63,6 +63,7 @@ static int isert_rdma_post_recvl(struct isert_conn *isert_conn); static int isert_rdma_accept(struct isert_conn *isert_conn); +struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); static inline bool isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) @@ -862,17 +863,38 @@ isert_conn_terminate(struct isert_conn *isert_conn) } static int -isert_disconnected_handler(struct rdma_cm_id *cma_id) +isert_np_cma_handler(struct isert_np *isert_np, + enum rdma_cm_event_type event) { - struct isert_conn *isert_conn; - - if (!cma_id->qp) { - struct isert_np *isert_np = cma_id->context; + isert_dbg("isert np %p, handling event %d\n", isert_np, event); + switch (event) { + case RDMA_CM_EVENT_ADDR_CHANGE: + isert_np->np_cm_id = isert_setup_id(isert_np); + if (!IS_ERR(isert_np->np_cm_id)) + break; + isert_err("isert np %p setup id failed: %ld\n", isert_np, + PTR_ERR(isert_np->np_cm_id)); + case RDMA_CM_EVENT_DEVICE_REMOVAL: isert_np->np_cm_id = NULL; - return -1; + break; + default: + isert_err("isert np %p Unexpected event %d\n", + isert_np, event); } + return -1; +} + +static int +isert_disconnected_handler(struct rdma_cm_id *cma_id, + enum rdma_cm_event_type event) +{ + struct isert_conn *isert_conn; + + if (!cma_id->qp) + return isert_np_cma_handler(cma_id->context, event); + isert_conn = (struct isert_conn *)cma_id->context; mutex_lock(&isert_conn->conn_mutex); @@ -915,7 +937,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) case RDMA_CM_EVENT_DISCONNECTED: /* FALLTHRU */ case RDMA_CM_EVENT_DEVICE_REMOVAL: /* FALLTHRU */ case RDMA_CM_EVENT_TIMEWAIT_EXIT: /* FALLTHRU */ - ret = isert_disconnected_handler(cma_id); + ret = isert_disconnected_handler(cma_id, event->event); break; case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */ case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html