diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/cm.c | 115 | ||||
-rw-r--r-- | drivers/infiniband/core/ucm.c | 12 |
2 files changed, 94 insertions, 33 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 78d9c0c33148..e5dc4530808a 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -147,12 +147,12 @@ struct cm_id_private { | |||
147 | __be32 rq_psn; | 147 | __be32 rq_psn; |
148 | int timeout_ms; | 148 | int timeout_ms; |
149 | enum ib_mtu path_mtu; | 149 | enum ib_mtu path_mtu; |
150 | __be16 pkey; | ||
150 | u8 private_data_len; | 151 | u8 private_data_len; |
151 | u8 max_cm_retries; | 152 | u8 max_cm_retries; |
152 | u8 peer_to_peer; | 153 | u8 peer_to_peer; |
153 | u8 responder_resources; | 154 | u8 responder_resources; |
154 | u8 initiator_depth; | 155 | u8 initiator_depth; |
155 | u8 local_ack_timeout; | ||
156 | u8 retry_count; | 156 | u8 retry_count; |
157 | u8 rnr_retry_count; | 157 | u8 rnr_retry_count; |
158 | u8 service_timeout; | 158 | u8 service_timeout; |
@@ -690,7 +690,7 @@ static void cm_enter_timewait(struct cm_id_private *cm_id_priv) | |||
690 | * timewait before notifying the user that we've exited timewait. | 690 | * timewait before notifying the user that we've exited timewait. |
691 | */ | 691 | */ |
692 | cm_id_priv->id.state = IB_CM_TIMEWAIT; | 692 | cm_id_priv->id.state = IB_CM_TIMEWAIT; |
693 | wait_time = cm_convert_to_ms(cm_id_priv->local_ack_timeout); | 693 | wait_time = cm_convert_to_ms(cm_id_priv->av.packet_life_time + 1); |
694 | queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, | 694 | queue_delayed_work(cm.wq, &cm_id_priv->timewait_info->work.work, |
695 | msecs_to_jiffies(wait_time)); | 695 | msecs_to_jiffies(wait_time)); |
696 | cm_id_priv->timewait_info = NULL; | 696 | cm_id_priv->timewait_info = NULL; |
@@ -1009,6 +1009,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, | |||
1009 | cm_id_priv->responder_resources = param->responder_resources; | 1009 | cm_id_priv->responder_resources = param->responder_resources; |
1010 | cm_id_priv->retry_count = param->retry_count; | 1010 | cm_id_priv->retry_count = param->retry_count; |
1011 | cm_id_priv->path_mtu = param->primary_path->mtu; | 1011 | cm_id_priv->path_mtu = param->primary_path->mtu; |
1012 | cm_id_priv->pkey = param->primary_path->pkey; | ||
1012 | cm_id_priv->qp_type = param->qp_type; | 1013 | cm_id_priv->qp_type = param->qp_type; |
1013 | 1014 | ||
1014 | ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); | 1015 | ret = cm_alloc_msg(cm_id_priv, &cm_id_priv->msg); |
@@ -1023,8 +1024,6 @@ int ib_send_cm_req(struct ib_cm_id *cm_id, | |||
1023 | 1024 | ||
1024 | cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg); | 1025 | cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg); |
1025 | cm_id_priv->rq_psn = cm_req_get_starting_psn(req_msg); | 1026 | cm_id_priv->rq_psn = cm_req_get_starting_psn(req_msg); |
1026 | cm_id_priv->local_ack_timeout = | ||
1027 | cm_req_get_primary_local_ack_timeout(req_msg); | ||
1028 | 1027 | ||
1029 | spin_lock_irqsave(&cm_id_priv->lock, flags); | 1028 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
1030 | ret = ib_post_send_mad(cm_id_priv->msg, NULL); | 1029 | ret = ib_post_send_mad(cm_id_priv->msg, NULL); |
@@ -1409,9 +1408,8 @@ static int cm_req_handler(struct cm_work *work) | |||
1409 | cm_id_priv->initiator_depth = cm_req_get_resp_res(req_msg); | 1408 | cm_id_priv->initiator_depth = cm_req_get_resp_res(req_msg); |
1410 | cm_id_priv->responder_resources = cm_req_get_init_depth(req_msg); | 1409 | cm_id_priv->responder_resources = cm_req_get_init_depth(req_msg); |
1411 | cm_id_priv->path_mtu = cm_req_get_path_mtu(req_msg); | 1410 | cm_id_priv->path_mtu = cm_req_get_path_mtu(req_msg); |
1411 | cm_id_priv->pkey = req_msg->pkey; | ||
1412 | cm_id_priv->sq_psn = cm_req_get_starting_psn(req_msg); | 1412 | cm_id_priv->sq_psn = cm_req_get_starting_psn(req_msg); |
1413 | cm_id_priv->local_ack_timeout = | ||
1414 | cm_req_get_primary_local_ack_timeout(req_msg); | ||
1415 | cm_id_priv->retry_count = cm_req_get_retry_count(req_msg); | 1413 | cm_id_priv->retry_count = cm_req_get_retry_count(req_msg); |
1416 | cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); | 1414 | cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); |
1417 | cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); | 1415 | cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); |
@@ -1715,7 +1713,7 @@ static int cm_establish_handler(struct cm_work *work) | |||
1715 | unsigned long flags; | 1713 | unsigned long flags; |
1716 | int ret; | 1714 | int ret; |
1717 | 1715 | ||
1718 | /* See comment in ib_cm_establish about lookup. */ | 1716 | /* See comment in cm_establish about lookup. */ |
1719 | cm_id_priv = cm_acquire_id(work->local_id, work->remote_id); | 1717 | cm_id_priv = cm_acquire_id(work->local_id, work->remote_id); |
1720 | if (!cm_id_priv) | 1718 | if (!cm_id_priv) |
1721 | return -EINVAL; | 1719 | return -EINVAL; |
@@ -2401,11 +2399,16 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id, | |||
2401 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); | 2399 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
2402 | spin_lock_irqsave(&cm_id_priv->lock, flags); | 2400 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
2403 | if (cm_id->state != IB_CM_ESTABLISHED || | 2401 | if (cm_id->state != IB_CM_ESTABLISHED || |
2404 | cm_id->lap_state != IB_CM_LAP_IDLE) { | 2402 | (cm_id->lap_state != IB_CM_LAP_UNINIT && |
2403 | cm_id->lap_state != IB_CM_LAP_IDLE)) { | ||
2405 | ret = -EINVAL; | 2404 | ret = -EINVAL; |
2406 | goto out; | 2405 | goto out; |
2407 | } | 2406 | } |
2408 | 2407 | ||
2408 | ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av); | ||
2409 | if (ret) | ||
2410 | goto out; | ||
2411 | |||
2409 | ret = cm_alloc_msg(cm_id_priv, &msg); | 2412 | ret = cm_alloc_msg(cm_id_priv, &msg); |
2410 | if (ret) | 2413 | if (ret) |
2411 | goto out; | 2414 | goto out; |
@@ -2430,7 +2433,8 @@ out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); | |||
2430 | } | 2433 | } |
2431 | EXPORT_SYMBOL(ib_send_cm_lap); | 2434 | EXPORT_SYMBOL(ib_send_cm_lap); |
2432 | 2435 | ||
2433 | static void cm_format_path_from_lap(struct ib_sa_path_rec *path, | 2436 | static void cm_format_path_from_lap(struct cm_id_private *cm_id_priv, |
2437 | struct ib_sa_path_rec *path, | ||
2434 | struct cm_lap_msg *lap_msg) | 2438 | struct cm_lap_msg *lap_msg) |
2435 | { | 2439 | { |
2436 | memset(path, 0, sizeof *path); | 2440 | memset(path, 0, sizeof *path); |
@@ -2442,10 +2446,10 @@ static void cm_format_path_from_lap(struct ib_sa_path_rec *path, | |||
2442 | path->hop_limit = lap_msg->alt_hop_limit; | 2446 | path->hop_limit = lap_msg->alt_hop_limit; |
2443 | path->traffic_class = cm_lap_get_traffic_class(lap_msg); | 2447 | path->traffic_class = cm_lap_get_traffic_class(lap_msg); |
2444 | path->reversible = 1; | 2448 | path->reversible = 1; |
2445 | /* pkey is same as in REQ */ | 2449 | path->pkey = cm_id_priv->pkey; |
2446 | path->sl = cm_lap_get_sl(lap_msg); | 2450 | path->sl = cm_lap_get_sl(lap_msg); |
2447 | path->mtu_selector = IB_SA_EQ; | 2451 | path->mtu_selector = IB_SA_EQ; |
2448 | /* mtu is same as in REQ */ | 2452 | path->mtu = cm_id_priv->path_mtu; |
2449 | path->rate_selector = IB_SA_EQ; | 2453 | path->rate_selector = IB_SA_EQ; |
2450 | path->rate = cm_lap_get_packet_rate(lap_msg); | 2454 | path->rate = cm_lap_get_packet_rate(lap_msg); |
2451 | path->packet_life_time_selector = IB_SA_EQ; | 2455 | path->packet_life_time_selector = IB_SA_EQ; |
@@ -2471,7 +2475,7 @@ static int cm_lap_handler(struct cm_work *work) | |||
2471 | 2475 | ||
2472 | param = &work->cm_event.param.lap_rcvd; | 2476 | param = &work->cm_event.param.lap_rcvd; |
2473 | param->alternate_path = &work->path[0]; | 2477 | param->alternate_path = &work->path[0]; |
2474 | cm_format_path_from_lap(param->alternate_path, lap_msg); | 2478 | cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg); |
2475 | work->cm_event.private_data = &lap_msg->private_data; | 2479 | work->cm_event.private_data = &lap_msg->private_data; |
2476 | 2480 | ||
2477 | spin_lock_irqsave(&cm_id_priv->lock, flags); | 2481 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
@@ -2479,6 +2483,7 @@ static int cm_lap_handler(struct cm_work *work) | |||
2479 | goto unlock; | 2483 | goto unlock; |
2480 | 2484 | ||
2481 | switch (cm_id_priv->id.lap_state) { | 2485 | switch (cm_id_priv->id.lap_state) { |
2486 | case IB_CM_LAP_UNINIT: | ||
2482 | case IB_CM_LAP_IDLE: | 2487 | case IB_CM_LAP_IDLE: |
2483 | break; | 2488 | break; |
2484 | case IB_CM_MRA_LAP_SENT: | 2489 | case IB_CM_MRA_LAP_SENT: |
@@ -2501,6 +2506,10 @@ static int cm_lap_handler(struct cm_work *work) | |||
2501 | 2506 | ||
2502 | cm_id_priv->id.lap_state = IB_CM_LAP_RCVD; | 2507 | cm_id_priv->id.lap_state = IB_CM_LAP_RCVD; |
2503 | cm_id_priv->tid = lap_msg->hdr.tid; | 2508 | cm_id_priv->tid = lap_msg->hdr.tid; |
2509 | cm_init_av_for_response(work->port, work->mad_recv_wc->wc, | ||
2510 | work->mad_recv_wc->recv_buf.grh, | ||
2511 | &cm_id_priv->av); | ||
2512 | cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av); | ||
2504 | ret = atomic_inc_and_test(&cm_id_priv->work_count); | 2513 | ret = atomic_inc_and_test(&cm_id_priv->work_count); |
2505 | if (!ret) | 2514 | if (!ret) |
2506 | list_add_tail(&work->list, &cm_id_priv->work_list); | 2515 | list_add_tail(&work->list, &cm_id_priv->work_list); |
@@ -3039,7 +3048,7 @@ static void cm_work_handler(void *data) | |||
3039 | cm_free_work(work); | 3048 | cm_free_work(work); |
3040 | } | 3049 | } |
3041 | 3050 | ||
3042 | int ib_cm_establish(struct ib_cm_id *cm_id) | 3051 | static int cm_establish(struct ib_cm_id *cm_id) |
3043 | { | 3052 | { |
3044 | struct cm_id_private *cm_id_priv; | 3053 | struct cm_id_private *cm_id_priv; |
3045 | struct cm_work *work; | 3054 | struct cm_work *work; |
@@ -3087,7 +3096,44 @@ int ib_cm_establish(struct ib_cm_id *cm_id) | |||
3087 | out: | 3096 | out: |
3088 | return ret; | 3097 | return ret; |
3089 | } | 3098 | } |
3090 | EXPORT_SYMBOL(ib_cm_establish); | 3099 | |
3100 | static int cm_migrate(struct ib_cm_id *cm_id) | ||
3101 | { | ||
3102 | struct cm_id_private *cm_id_priv; | ||
3103 | unsigned long flags; | ||
3104 | int ret = 0; | ||
3105 | |||
3106 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); | ||
3107 | spin_lock_irqsave(&cm_id_priv->lock, flags); | ||
3108 | if (cm_id->state == IB_CM_ESTABLISHED && | ||
3109 | (cm_id->lap_state == IB_CM_LAP_UNINIT || | ||
3110 | cm_id->lap_state == IB_CM_LAP_IDLE)) { | ||
3111 | cm_id->lap_state = IB_CM_LAP_IDLE; | ||
3112 | cm_id_priv->av = cm_id_priv->alt_av; | ||
3113 | } else | ||
3114 | ret = -EINVAL; | ||
3115 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); | ||
3116 | |||
3117 | return ret; | ||
3118 | } | ||
3119 | |||
3120 | int ib_cm_notify(struct ib_cm_id *cm_id, enum ib_event_type event) | ||
3121 | { | ||
3122 | int ret; | ||
3123 | |||
3124 | switch (event) { | ||
3125 | case IB_EVENT_COMM_EST: | ||
3126 | ret = cm_establish(cm_id); | ||
3127 | break; | ||
3128 | case IB_EVENT_PATH_MIG: | ||
3129 | ret = cm_migrate(cm_id); | ||
3130 | break; | ||
3131 | default: | ||
3132 | ret = -EINVAL; | ||
3133 | } | ||
3134 | return ret; | ||
3135 | } | ||
3136 | EXPORT_SYMBOL(ib_cm_notify); | ||
3091 | 3137 | ||
3092 | static void cm_recv_handler(struct ib_mad_agent *mad_agent, | 3138 | static void cm_recv_handler(struct ib_mad_agent *mad_agent, |
3093 | struct ib_mad_recv_wc *mad_recv_wc) | 3139 | struct ib_mad_recv_wc *mad_recv_wc) |
@@ -3220,6 +3266,9 @@ static int cm_init_qp_rtr_attr(struct cm_id_private *cm_id_priv, | |||
3220 | if (cm_id_priv->alt_av.ah_attr.dlid) { | 3266 | if (cm_id_priv->alt_av.ah_attr.dlid) { |
3221 | *qp_attr_mask |= IB_QP_ALT_PATH; | 3267 | *qp_attr_mask |= IB_QP_ALT_PATH; |
3222 | qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; | 3268 | qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; |
3269 | qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index; | ||
3270 | qp_attr->alt_timeout = | ||
3271 | cm_id_priv->alt_av.packet_life_time + 1; | ||
3223 | qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; | 3272 | qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; |
3224 | } | 3273 | } |
3225 | ret = 0; | 3274 | ret = 0; |
@@ -3246,19 +3295,31 @@ static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv, | |||
3246 | case IB_CM_REP_SENT: | 3295 | case IB_CM_REP_SENT: |
3247 | case IB_CM_MRA_REP_RCVD: | 3296 | case IB_CM_MRA_REP_RCVD: |
3248 | case IB_CM_ESTABLISHED: | 3297 | case IB_CM_ESTABLISHED: |
3249 | *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN; | 3298 | if (cm_id_priv->id.lap_state == IB_CM_LAP_UNINIT) { |
3250 | qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn); | 3299 | *qp_attr_mask = IB_QP_STATE | IB_QP_SQ_PSN; |
3251 | if (cm_id_priv->qp_type == IB_QPT_RC) { | 3300 | qp_attr->sq_psn = be32_to_cpu(cm_id_priv->sq_psn); |
3252 | *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | | 3301 | if (cm_id_priv->qp_type == IB_QPT_RC) { |
3253 | IB_QP_RNR_RETRY | | 3302 | *qp_attr_mask |= IB_QP_TIMEOUT | IB_QP_RETRY_CNT | |
3254 | IB_QP_MAX_QP_RD_ATOMIC; | 3303 | IB_QP_RNR_RETRY | |
3255 | qp_attr->timeout = cm_id_priv->local_ack_timeout; | 3304 | IB_QP_MAX_QP_RD_ATOMIC; |
3256 | qp_attr->retry_cnt = cm_id_priv->retry_count; | 3305 | qp_attr->timeout = |
3257 | qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; | 3306 | cm_id_priv->av.packet_life_time + 1; |
3258 | qp_attr->max_rd_atomic = cm_id_priv->initiator_depth; | 3307 | qp_attr->retry_cnt = cm_id_priv->retry_count; |
3259 | } | 3308 | qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; |
3260 | if (cm_id_priv->alt_av.ah_attr.dlid) { | 3309 | qp_attr->max_rd_atomic = |
3261 | *qp_attr_mask |= IB_QP_PATH_MIG_STATE; | 3310 | cm_id_priv->initiator_depth; |
3311 | } | ||
3312 | if (cm_id_priv->alt_av.ah_attr.dlid) { | ||
3313 | *qp_attr_mask |= IB_QP_PATH_MIG_STATE; | ||
3314 | qp_attr->path_mig_state = IB_MIG_REARM; | ||
3315 | } | ||
3316 | } else { | ||
3317 | *qp_attr_mask = IB_QP_ALT_PATH | IB_QP_PATH_MIG_STATE; | ||
3318 | qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; | ||
3319 | qp_attr->alt_pkey_index = cm_id_priv->alt_av.pkey_index; | ||
3320 | qp_attr->alt_timeout = | ||
3321 | cm_id_priv->alt_av.packet_life_time + 1; | ||
3322 | qp_attr->alt_ah_attr = cm_id_priv->alt_av.ah_attr; | ||
3262 | qp_attr->path_mig_state = IB_MIG_REARM; | 3323 | qp_attr->path_mig_state = IB_MIG_REARM; |
3263 | } | 3324 | } |
3264 | ret = 0; | 3325 | ret = 0; |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index b4894ba223b7..1f4f2d2cfa2e 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
@@ -683,11 +683,11 @@ out: | |||
683 | return result; | 683 | return result; |
684 | } | 684 | } |
685 | 685 | ||
686 | static ssize_t ib_ucm_establish(struct ib_ucm_file *file, | 686 | static ssize_t ib_ucm_notify(struct ib_ucm_file *file, |
687 | const char __user *inbuf, | 687 | const char __user *inbuf, |
688 | int in_len, int out_len) | 688 | int in_len, int out_len) |
689 | { | 689 | { |
690 | struct ib_ucm_establish cmd; | 690 | struct ib_ucm_notify cmd; |
691 | struct ib_ucm_context *ctx; | 691 | struct ib_ucm_context *ctx; |
692 | int result; | 692 | int result; |
693 | 693 | ||
@@ -698,7 +698,7 @@ static ssize_t ib_ucm_establish(struct ib_ucm_file *file, | |||
698 | if (IS_ERR(ctx)) | 698 | if (IS_ERR(ctx)) |
699 | return PTR_ERR(ctx); | 699 | return PTR_ERR(ctx); |
700 | 700 | ||
701 | result = ib_cm_establish(ctx->cm_id); | 701 | result = ib_cm_notify(ctx->cm_id, (enum ib_event_type) cmd.event); |
702 | ib_ucm_ctx_put(ctx); | 702 | ib_ucm_ctx_put(ctx); |
703 | return result; | 703 | return result; |
704 | } | 704 | } |
@@ -1105,7 +1105,7 @@ static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file, | |||
1105 | [IB_USER_CM_CMD_DESTROY_ID] = ib_ucm_destroy_id, | 1105 | [IB_USER_CM_CMD_DESTROY_ID] = ib_ucm_destroy_id, |
1106 | [IB_USER_CM_CMD_ATTR_ID] = ib_ucm_attr_id, | 1106 | [IB_USER_CM_CMD_ATTR_ID] = ib_ucm_attr_id, |
1107 | [IB_USER_CM_CMD_LISTEN] = ib_ucm_listen, | 1107 | [IB_USER_CM_CMD_LISTEN] = ib_ucm_listen, |
1108 | [IB_USER_CM_CMD_ESTABLISH] = ib_ucm_establish, | 1108 | [IB_USER_CM_CMD_NOTIFY] = ib_ucm_notify, |
1109 | [IB_USER_CM_CMD_SEND_REQ] = ib_ucm_send_req, | 1109 | [IB_USER_CM_CMD_SEND_REQ] = ib_ucm_send_req, |
1110 | [IB_USER_CM_CMD_SEND_REP] = ib_ucm_send_rep, | 1110 | [IB_USER_CM_CMD_SEND_REP] = ib_ucm_send_rep, |
1111 | [IB_USER_CM_CMD_SEND_RTU] = ib_ucm_send_rtu, | 1111 | [IB_USER_CM_CMD_SEND_RTU] = ib_ucm_send_rtu, |