aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFaisal Latif <faisal.latif@intel.com>2009-12-09 18:54:14 -0500
committerRoland Dreier <rolandd@cisco.com>2009-12-09 18:54:14 -0500
commitf9f3f1e08b4d66bfda2a0c2d49a26c80489a0725 (patch)
tree22b2c03874a49781f9c9681aad807d75b572c316 /drivers
parentc5a7d4897156667a58fd8479f6227143573fe82d (diff)
RDMA/nes: Abnormal listener exit causes loopback node crash
When the listener is destroyed for a loopback connection, the listener node gets a reset event. This causes a crash as the listener is not expecting a reset event. Code review of cm_event_reset() during debugging showed the cm_id ref count is incremented after calling its event handler and not before. Signed-off-by: Faisal Latif <faisal.latif@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c16
1 files changed, 3 insertions, 13 deletions
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index ec04786b6069..20e21f1a18b9 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1014,18 +1014,6 @@ static int mini_cm_dec_refcnt_listen(struct nes_cm_core *cm_core,
1014 cm_node->state = NES_CM_STATE_LISTENER_DESTROYED; 1014 cm_node->state = NES_CM_STATE_LISTENER_DESTROYED;
1015 loopback->state = NES_CM_STATE_CLOSED; 1015 loopback->state = NES_CM_STATE_CLOSED;
1016 1016
1017 event.cm_node = cm_node;
1018 event.cm_info.rem_addr =
1019 cm_node->rem_addr;
1020 event.cm_info.loc_addr =
1021 cm_node->loc_addr;
1022 event.cm_info.rem_port =
1023 cm_node->rem_port;
1024 event.cm_info.loc_port =
1025 cm_node->loc_port;
1026 event.cm_info.cm_id = cm_node->cm_id;
1027 cm_event_reset(&event);
1028
1029 rem_ref_cm_node(cm_node->cm_core, 1017 rem_ref_cm_node(cm_node->cm_core,
1030 cm_node); 1018 cm_node);
1031 1019
@@ -3440,6 +3428,8 @@ static void cm_event_reset(struct nes_cm_event *event)
3440 3428
3441 nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id); 3429 nes_debug(NES_DBG_CM, "%p - cm_id = %p\n", event->cm_node, cm_id);
3442 nesqp = cm_id->provider_data; 3430 nesqp = cm_id->provider_data;
3431 if (!nesqp)
3432 return;
3443 3433
3444 nesqp->cm_id = NULL; 3434 nesqp->cm_id = NULL;
3445 /* cm_id->provider_data = NULL; */ 3435 /* cm_id->provider_data = NULL; */
@@ -3451,8 +3441,8 @@ static void cm_event_reset(struct nes_cm_event *event)
3451 cm_event.private_data = NULL; 3441 cm_event.private_data = NULL;
3452 cm_event.private_data_len = 0; 3442 cm_event.private_data_len = 0;
3453 3443
3454 ret = cm_id->event_handler(cm_id, &cm_event);
3455 cm_id->add_ref(cm_id); 3444 cm_id->add_ref(cm_id);
3445 ret = cm_id->event_handler(cm_id, &cm_event);
3456 atomic_inc(&cm_closes); 3446 atomic_inc(&cm_closes);
3457 cm_event.event = IW_CM_EVENT_CLOSE; 3447 cm_event.event = IW_CM_EVENT_CLOSE;
3458 cm_event.status = IW_CM_EVENT_STATUS_OK; 3448 cm_event.status = IW_CM_EVENT_STATUS_OK;