| .. | .. |
|---|
| 505 | 505 | return id_priv->id.route.addr.src_addr.ss_family; |
|---|
| 506 | 506 | } |
|---|
| 507 | 507 | |
|---|
| 508 | | -static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey) |
|---|
| 508 | +static int cma_set_default_qkey(struct rdma_id_private *id_priv) |
|---|
| 509 | 509 | { |
|---|
| 510 | 510 | struct ib_sa_mcmember_rec rec; |
|---|
| 511 | 511 | int ret = 0; |
|---|
| 512 | | - |
|---|
| 513 | | - if (id_priv->qkey) { |
|---|
| 514 | | - if (qkey && id_priv->qkey != qkey) |
|---|
| 515 | | - return -EINVAL; |
|---|
| 516 | | - return 0; |
|---|
| 517 | | - } |
|---|
| 518 | | - |
|---|
| 519 | | - if (qkey) { |
|---|
| 520 | | - id_priv->qkey = qkey; |
|---|
| 521 | | - return 0; |
|---|
| 522 | | - } |
|---|
| 523 | 512 | |
|---|
| 524 | 513 | switch (id_priv->id.ps) { |
|---|
| 525 | 514 | case RDMA_PS_UDP: |
|---|
| .. | .. |
|---|
| 538 | 527 | break; |
|---|
| 539 | 528 | } |
|---|
| 540 | 529 | return ret; |
|---|
| 530 | +} |
|---|
| 531 | + |
|---|
| 532 | +static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey) |
|---|
| 533 | +{ |
|---|
| 534 | + if (!qkey || |
|---|
| 535 | + (id_priv->qkey && (id_priv->qkey != qkey))) |
|---|
| 536 | + return -EINVAL; |
|---|
| 537 | + |
|---|
| 538 | + id_priv->qkey = qkey; |
|---|
| 539 | + return 0; |
|---|
| 541 | 540 | } |
|---|
| 542 | 541 | |
|---|
| 543 | 542 | static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr) |
|---|
| .. | .. |
|---|
| 1107 | 1106 | *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT; |
|---|
| 1108 | 1107 | |
|---|
| 1109 | 1108 | if (id_priv->id.qp_type == IB_QPT_UD) { |
|---|
| 1110 | | - ret = cma_set_qkey(id_priv, 0); |
|---|
| 1109 | + ret = cma_set_default_qkey(id_priv); |
|---|
| 1111 | 1110 | if (ret) |
|---|
| 1112 | 1111 | return ret; |
|---|
| 1113 | 1112 | |
|---|
| .. | .. |
|---|
| 1793 | 1792 | { |
|---|
| 1794 | 1793 | switch (state) { |
|---|
| 1795 | 1794 | case RDMA_CM_ADDR_QUERY: |
|---|
| 1795 | + /* |
|---|
| 1796 | + * We can avoid doing the rdma_addr_cancel() based on state, |
|---|
| 1797 | + * only RDMA_CM_ADDR_QUERY has a work that could still execute. |
|---|
| 1798 | + * Notice that the addr_handler work could still be exiting |
|---|
| 1799 | + * outside this state, however due to the interaction with the |
|---|
| 1800 | + * handler_mutex the work is guaranteed not to touch id_priv |
|---|
| 1801 | + * during exit. |
|---|
| 1802 | + */ |
|---|
| 1796 | 1803 | rdma_addr_cancel(&id_priv->id.route.addr.dev_addr); |
|---|
| 1797 | 1804 | break; |
|---|
| 1798 | 1805 | case RDMA_CM_ROUTE_QUERY: |
|---|
| .. | .. |
|---|
| 3070 | 3077 | route->path_rec->traffic_class = tos; |
|---|
| 3071 | 3078 | route->path_rec->mtu = iboe_get_mtu(ndev->mtu); |
|---|
| 3072 | 3079 | route->path_rec->rate_selector = IB_SA_EQ; |
|---|
| 3073 | | - route->path_rec->rate = iboe_get_rate(ndev); |
|---|
| 3080 | + route->path_rec->rate = IB_RATE_PORT_CURRENT; |
|---|
| 3074 | 3081 | dev_put(ndev); |
|---|
| 3075 | 3082 | route->path_rec->packet_life_time_selector = IB_SA_EQ; |
|---|
| 3076 | 3083 | /* In case ACK timeout is set, use this value to calculate |
|---|
| .. | .. |
|---|
| 3402 | 3409 | if (dst_addr->sa_family == AF_IB) { |
|---|
| 3403 | 3410 | ret = cma_resolve_ib_addr(id_priv); |
|---|
| 3404 | 3411 | } else { |
|---|
| 3412 | + /* |
|---|
| 3413 | + * The FSM can return back to RDMA_CM_ADDR_BOUND after |
|---|
| 3414 | + * rdma_resolve_ip() is called, eg through the error |
|---|
| 3415 | + * path in addr_handler(). If this happens the existing |
|---|
| 3416 | + * request must be canceled before issuing a new one. |
|---|
| 3417 | + * Since canceling a request is a bit slow and this |
|---|
| 3418 | + * oddball path is rare, keep track once a request has |
|---|
| 3419 | + * been issued. The track turns out to be a permanent |
|---|
| 3420 | + * state since this is the only cancel as it is |
|---|
| 3421 | + * immediately before rdma_resolve_ip(). |
|---|
| 3422 | + */ |
|---|
| 3423 | + if (id_priv->used_resolve_ip) |
|---|
| 3424 | + rdma_addr_cancel(&id->route.addr.dev_addr); |
|---|
| 3425 | + else |
|---|
| 3426 | + id_priv->used_resolve_ip = 1; |
|---|
| 3405 | 3427 | ret = rdma_resolve_ip(cma_src_addr(id_priv), dst_addr, |
|---|
| 3406 | 3428 | &id->route.addr.dev_addr, |
|---|
| 3407 | 3429 | timeout_ms, addr_handler, |
|---|
| .. | .. |
|---|
| 4312 | 4334 | memset(&rep, 0, sizeof rep); |
|---|
| 4313 | 4335 | rep.status = status; |
|---|
| 4314 | 4336 | if (status == IB_SIDR_SUCCESS) { |
|---|
| 4315 | | - ret = cma_set_qkey(id_priv, qkey); |
|---|
| 4337 | + if (qkey) |
|---|
| 4338 | + ret = cma_set_qkey(id_priv, qkey); |
|---|
| 4339 | + else |
|---|
| 4340 | + ret = cma_set_default_qkey(id_priv); |
|---|
| 4316 | 4341 | if (ret) |
|---|
| 4317 | 4342 | return ret; |
|---|
| 4318 | 4343 | rep.qp_num = id_priv->qp_num; |
|---|
| .. | .. |
|---|
| 4516 | 4541 | enum ib_gid_type gid_type; |
|---|
| 4517 | 4542 | struct net_device *ndev; |
|---|
| 4518 | 4543 | |
|---|
| 4519 | | - if (!status) |
|---|
| 4520 | | - status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); |
|---|
| 4521 | | - else |
|---|
| 4544 | + if (status) |
|---|
| 4522 | 4545 | pr_debug_ratelimited("RDMA CM: MULTICAST_ERROR: failed to join multicast. status %d\n", |
|---|
| 4523 | 4546 | status); |
|---|
| 4524 | 4547 | |
|---|
| .. | .. |
|---|
| 4546 | 4569 | } |
|---|
| 4547 | 4570 | |
|---|
| 4548 | 4571 | event->param.ud.qp_num = 0xFFFFFF; |
|---|
| 4549 | | - event->param.ud.qkey = be32_to_cpu(multicast->rec.qkey); |
|---|
| 4572 | + event->param.ud.qkey = id_priv->qkey; |
|---|
| 4550 | 4573 | |
|---|
| 4551 | 4574 | out: |
|---|
| 4552 | 4575 | if (ndev) |
|---|
| .. | .. |
|---|
| 4565 | 4588 | READ_ONCE(id_priv->state) == RDMA_CM_DESTROYING) |
|---|
| 4566 | 4589 | goto out; |
|---|
| 4567 | 4590 | |
|---|
| 4568 | | - cma_make_mc_event(status, id_priv, multicast, &event, mc); |
|---|
| 4569 | | - ret = cma_cm_event_handler(id_priv, &event); |
|---|
| 4591 | + ret = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); |
|---|
| 4592 | + if (!ret) { |
|---|
| 4593 | + cma_make_mc_event(status, id_priv, multicast, &event, mc); |
|---|
| 4594 | + ret = cma_cm_event_handler(id_priv, &event); |
|---|
| 4595 | + } |
|---|
| 4570 | 4596 | rdma_destroy_ah_attr(&event.param.ud.ah_attr); |
|---|
| 4571 | 4597 | WARN_ON(ret); |
|---|
| 4572 | 4598 | |
|---|
| .. | .. |
|---|
| 4619 | 4645 | if (ret) |
|---|
| 4620 | 4646 | return ret; |
|---|
| 4621 | 4647 | |
|---|
| 4622 | | - ret = cma_set_qkey(id_priv, 0); |
|---|
| 4623 | | - if (ret) |
|---|
| 4624 | | - return ret; |
|---|
| 4648 | + if (!id_priv->qkey) { |
|---|
| 4649 | + ret = cma_set_default_qkey(id_priv); |
|---|
| 4650 | + if (ret) |
|---|
| 4651 | + return ret; |
|---|
| 4652 | + } |
|---|
| 4625 | 4653 | |
|---|
| 4626 | 4654 | cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); |
|---|
| 4627 | 4655 | rec.qkey = cpu_to_be32(id_priv->qkey); |
|---|
| .. | .. |
|---|
| 4695 | 4723 | int err = 0; |
|---|
| 4696 | 4724 | struct sockaddr *addr = (struct sockaddr *)&mc->addr; |
|---|
| 4697 | 4725 | struct net_device *ndev = NULL; |
|---|
| 4698 | | - struct ib_sa_multicast ib; |
|---|
| 4726 | + struct ib_sa_multicast ib = {}; |
|---|
| 4699 | 4727 | enum ib_gid_type gid_type; |
|---|
| 4700 | 4728 | bool send_only; |
|---|
| 4701 | 4729 | |
|---|
| .. | .. |
|---|
| 4709 | 4737 | cma_iboe_set_mgid(addr, &ib.rec.mgid, gid_type); |
|---|
| 4710 | 4738 | |
|---|
| 4711 | 4739 | ib.rec.pkey = cpu_to_be16(0xffff); |
|---|
| 4712 | | - if (id_priv->id.ps == RDMA_PS_UDP) |
|---|
| 4713 | | - ib.rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); |
|---|
| 4714 | | - |
|---|
| 4715 | 4740 | if (dev_addr->bound_dev_if) |
|---|
| 4716 | 4741 | ndev = dev_get_by_index(dev_addr->net, dev_addr->bound_dev_if); |
|---|
| 4717 | 4742 | if (!ndev) |
|---|
| 4718 | 4743 | return -ENODEV; |
|---|
| 4719 | 4744 | |
|---|
| 4720 | | - ib.rec.rate = iboe_get_rate(ndev); |
|---|
| 4745 | + ib.rec.rate = IB_RATE_PORT_CURRENT; |
|---|
| 4721 | 4746 | ib.rec.hop_limit = 1; |
|---|
| 4722 | 4747 | ib.rec.mtu = iboe_get_mtu(ndev->mtu); |
|---|
| 4723 | 4748 | |
|---|
| .. | .. |
|---|
| 4736 | 4761 | dev_put(ndev); |
|---|
| 4737 | 4762 | if (err || !ib.rec.mtu) |
|---|
| 4738 | 4763 | return err ?: -EINVAL; |
|---|
| 4764 | + |
|---|
| 4765 | + if (!id_priv->qkey) |
|---|
| 4766 | + cma_set_default_qkey(id_priv); |
|---|
| 4739 | 4767 | |
|---|
| 4740 | 4768 | rdma_ip2gid((struct sockaddr *)&id_priv->id.route.addr.src_addr, |
|---|
| 4741 | 4769 | &ib.rec.port_gid); |
|---|
| .. | .. |
|---|
| 4762 | 4790 | READ_ONCE(id_priv->state) != RDMA_CM_ADDR_RESOLVED)) |
|---|
| 4763 | 4791 | return -EINVAL; |
|---|
| 4764 | 4792 | |
|---|
| 4793 | + if (id_priv->id.qp_type != IB_QPT_UD) |
|---|
| 4794 | + return -EINVAL; |
|---|
| 4795 | + |
|---|
| 4765 | 4796 | mc = kzalloc(sizeof(*mc), GFP_KERNEL); |
|---|
| 4766 | 4797 | if (!mc) |
|---|
| 4767 | 4798 | return -ENOMEM; |
|---|