Unified · Split
| @@ -308,10 +308,11 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) · 307 unmodified lines | ||
| 308 | 308 | { |
| 309 | 309 | unsigned long flags; |
| 310 | 310 | int ret; |
| 311 | + static int next_id; | |
| 311 | 312 | |
| 312 | 313 | do { |
| 313 | 314 | spin_lock_irqsave(&cm.lock, flags); |
| 314 | − ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, | |
| 315 | + ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++, | |
| 315 | 316 | (__force int *) &cm_id_priv->id.local_id); |
| 316 | 317 | spin_unlock_irqrestore(&cm.lock, flags); |
| 317 | 318 | } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); |
| @@ -684,6 +685,13 @@ retest: · 366 unmodified lines | ||
| 684 | 685 | cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); |
| 685 | 686 | break; |
| 686 | 687 | case IB_CM_REQ_SENT: |
| 688 | + ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); | |
| 689 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); | |
| 690 | + ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, | |
| 691 | + &cm_id_priv->av.port->cm_dev->ca_guid, | |
| 692 | + sizeof cm_id_priv->av.port->cm_dev->ca_guid, | |
| 693 | + NULL, 0); | |
| 694 | + break; | |
| 687 | 695 | case IB_CM_MRA_REQ_RCVD: |
| 688 | 696 | case IB_CM_REP_SENT: |
| 689 | 697 | case IB_CM_MRA_REP_RCVD: |
| @@ -694,10 +702,8 @@ retest: · 4 unmodified lines | ||
| 694 | 702 | case IB_CM_REP_RCVD: |
| 695 | 703 | case IB_CM_MRA_REP_SENT: |
| 696 | 704 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
| 697 | − ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, | |
| 698 | − &cm_id_priv->av.port->cm_dev->ca_guid, | |
| 699 | − sizeof cm_id_priv->av.port->cm_dev->ca_guid, | |
| 700 | − NULL, 0); | |
| 705 | + ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, | |
| 706 | + NULL, 0, NULL, 0); | |
| 701 | 707 | break; |
| 702 | 708 | case IB_CM_ESTABLISHED: |
| 703 | 709 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
| @@ -197,8 +197,8 @@ static void send_handler(struct ib_mad_agent *agent, · 196 unmodified lines | ||
| 197 | 197 | memcpy(timeout->mad.data, packet->mad.data, |
| 198 | 198 | sizeof (struct ib_mad_hdr)); |
| 199 | 199 | |
| 200 | − if (!queue_packet(file, agent, timeout)) | |
| 201 | − return; | |
| 200 | + if (queue_packet(file, agent, timeout)) | |
| 201 | + kfree(timeout); | |
| 202 | 202 | } |
| 203 | 203 | out: |
| 204 | 204 | kfree(packet); |
| @@ -489,6 +489,7 @@ err_idr: · 488 unmodified lines | ||
| 489 | 489 | |
| 490 | 490 | err_unreg: |
| 491 | 491 | ib_dereg_mr(mr); |
| 492 | + atomic_dec(&pd->usecnt); | |
| 492 | 493 | |
| 493 | 494 | err_up: |
| 494 | 495 | up(&ib_uverbs_idr_mutex); |
| @@ -593,13 +594,18 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, · 98 unmodified lines | ||
| 593 | 594 | if (cmd.comp_vector >= file->device->num_comp_vectors) |
| 594 | 595 | return -EINVAL; |
| 595 | 596 | |
| 596 | − if (cmd.comp_channel >= 0) | |
| 597 | − ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); | |
| 598 | − | |
| 599 | 597 | uobj = kmalloc(sizeof *uobj, GFP_KERNEL); |
| 600 | 598 | if (!uobj) |
| 601 | 599 | return -ENOMEM; |
| 602 | 600 | |
| 601 | + if (cmd.comp_channel >= 0) { | |
| 602 | + ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); | |
| 603 | + if (!ev_file) { | |
| 604 | + ret = -EINVAL; | |
| 605 | + goto err; | |
| 606 | + } | |
| 607 | + } | |
| 608 | + | |
| 603 | 609 | uobj->uobject.user_handle = cmd.user_handle; |
| 604 | 610 | uobj->uobject.context = file->ucontext; |
| 605 | 611 | uobj->uverbs_file = file; |
| @@ -663,6 +669,8 @@ err_up: · 57 unmodified lines | ||
| 663 | 669 | ib_destroy_cq(cq); |
| 664 | 670 | |
| 665 | 671 | err: |
| 672 | + if (ev_file) | |
| 673 | + ib_uverbs_release_ucq(file, ev_file, uobj); | |
| 666 | 674 | kfree(uobj); |
| 667 | 675 | return ret; |
| 668 | 676 | } |
| @@ -935,6 +943,11 @@ err_idr: · 266 unmodified lines | ||
| 935 | 943 | |
| 936 | 944 | err_destroy: |
| 937 | 945 | ib_destroy_qp(qp); |
| 946 | + atomic_dec(&pd->usecnt); | |
| 947 | + atomic_dec(&attr.send_cq->usecnt); | |
| 948 | + atomic_dec(&attr.recv_cq->usecnt); | |
| 949 | + if (attr.srq) | |
| 950 | + atomic_dec(&attr.srq->usecnt); | |
| 938 | 951 | |
| 939 | 952 | err_up: |
| 940 | 953 | up(&ib_uverbs_idr_mutex); |
| @@ -1448,6 +1461,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, · 507 unmodified lines | ||
| 1448 | 1461 | attr.sl = cmd.attr.sl; |
| 1449 | 1462 | attr.src_path_bits = cmd.attr.src_path_bits; |
| 1450 | 1463 | attr.static_rate = cmd.attr.static_rate; |
| 1464 | + attr.ah_flags = cmd.attr.is_global ? IB_AH_GRH : 0; | |
| 1451 | 1465 | attr.port_num = cmd.attr.port_num; |
| 1452 | 1466 | attr.grh.flow_label = cmd.attr.grh.flow_label; |
| 1453 | 1467 | attr.grh.sgid_index = cmd.attr.grh.sgid_index; |
| @@ -1729,6 +1743,7 @@ err_idr: · 275 unmodified lines | ||
| 1729 | 1743 | |
| 1730 | 1744 | err_destroy: |
| 1731 | 1745 | ib_destroy_srq(srq); |
| 1746 | + atomic_dec(&pd->usecnt); | |
| 1732 | 1747 | |
| 1733 | 1748 | err_up: |
| 1734 | 1749 | up(&ib_uverbs_idr_mutex); |
| @@ -107,9 +107,9 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | if (wc->wc_flags & IB_WC_GRH) { |
| 109 | 109 | ah_attr.ah_flags = IB_AH_GRH; |
| 110 | − ah_attr.grh.dgid = grh->dgid; | |
| 110 | + ah_attr.grh.dgid = grh->sgid; | |
| 111 | 111 | |
| 112 | − ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, | |
| 112 | + ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num, | |
| 113 | 113 | &gid_index); |
| 114 | 114 | if (ret) |
| 115 | 115 | return ERR_PTR(ret); |
| @@ -937,10 +937,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, · 936 unmodified lines | ||
| 937 | 937 | if (err) |
| 938 | 938 | goto out; |
| 939 | 939 | |
| 940 | − MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | |
| 941 | − dev_lim->max_srq_sz = (1 << field) - 1; | |
| 942 | − MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | |
| 943 | − dev_lim->max_qp_sz = (1 << field) - 1; | |
| 944 | 940 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); |
| 945 | 941 | dev_lim->reserved_qps = 1 << (field & 0xf); |
| 946 | 942 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); |
| @@ -1056,6 +1052,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, · 109 unmodified lines | ||
| 1056 | 1052 | mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); |
| 1057 | 1053 | |
| 1058 | 1054 | if (mthca_is_memfree(dev)) { |
| 1055 | + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | |
| 1056 | + dev_lim->max_srq_sz = 1 << field; | |
| 1057 | + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | |
| 1058 | + dev_lim->max_qp_sz = 1 << field; | |
| 1059 | 1059 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET); |
| 1060 | 1060 | dev_lim->hca.arbel.resize_srq = field & 1; |
| 1061 | 1061 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); |
| @@ -1087,6 +1087,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, · 25 unmodified lines | ||
| 1087 | 1087 | mthca_dbg(dev, "Max ICM size %lld MB\n", |
| 1088 | 1088 | (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20); |
| 1089 | 1089 | } else { |
| 1090 | + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); | |
| 1091 | + dev_lim->max_srq_sz = (1 << field) - 1; | |
| 1092 | + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); | |
| 1093 | + dev_lim->max_qp_sz = (1 << field) - 1; | |
| 1090 | 1094 | MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); |
| 1091 | 1095 | dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); |
| 1092 | 1096 | dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; |
| @@ -128,12 +128,12 @@ struct mthca_err_cqe { · 127 unmodified lines | ||
| 128 | 128 | __be32 my_qpn; |
| 129 | 129 | u32 reserved1[3]; |
| 130 | 130 | u8 syndrome; |
| 131 | − u8 reserved2; | |
| 131 | + u8 vendor_err; | |
| 132 | 132 | __be16 db_cnt; |
| 133 | − u32 reserved3; | |
| 133 | + u32 reserved2; | |
| 134 | 134 | __be32 wqe; |
| 135 | 135 | u8 opcode; |
| 136 | − u8 reserved4[2]; | |
| 136 | + u8 reserved3[2]; | |
| 137 | 137 | u8 owner; |
| 138 | 138 | }; |
| 139 | 139 | |
| @@ -253,6 +253,15 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, · 113 unmodified lines | ||
| 253 | 253 | wake_up(&cq->wait); |
| 254 | 254 | } |
| 255 | 255 | |
| 256 | +static inline int is_recv_cqe(struct mthca_cqe *cqe) | |
| 257 | +{ | |
| 258 | + if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == | |
| 259 | + MTHCA_ERROR_CQE_OPCODE_MASK) | |
| 260 | + return !(cqe->opcode & 0x01); | |
| 261 | + else | |
| 262 | + return !(cqe->is_send & 0x80); | |
| 263 | +} | |
| 264 | + | |
| 256 | 265 | void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, |
| 257 | 266 | struct mthca_srq *srq) |
| 258 | 267 | { |
| @@ -296,7 +305,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, · 37 unmodified lines | ||
| 296 | 305 | while ((int) --prod_index - (int) cq->cons_index >= 0) { |
| 297 | 306 | cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); |
| 298 | 307 | if (cqe->my_qpn == cpu_to_be32(qpn)) { |
| 299 | − if (srq) | |
| 308 | + if (srq && is_recv_cqe(cqe)) | |
| 300 | 309 | mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); |
| 301 | 310 | ++nfreed; |
| 302 | 311 | } else if (nfreed) |
| @@ -333,8 +342,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, · 30 unmodified lines | ||
| 333 | 342 | } |
| 334 | 343 | |
| 335 | 344 | /* |
| 336 | − * For completions in error, only work request ID, status (and | |
| 337 | − * freed resource count for RD) have to be set. | |
| 345 | + * For completions in error, only work request ID, status, vendor error | |
| 346 | + * (and freed resource count for RD) have to be set. | |
| 338 | 347 | */ |
| 339 | 348 | switch (cqe->syndrome) { |
| 340 | 349 | case SYNDROME_LOCAL_LENGTH_ERR: |
| @@ -396,6 +405,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, · 55 unmodified lines | ||
| 396 | 405 | break; |
| 397 | 406 | } |
| 398 | 407 | |
| 408 | + entry->vendor_err = cqe->vendor_err; | |
| 409 | + | |
| 399 | 410 | /* |
| 400 | 411 | * Mem-free HCAs always generate one CQE per WQE, even in the |
| 401 | 412 | * error case, so we don't have to check the doorbell count, etc. |
| @@ -484,8 +484,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, · 483 unmodified lines | ||
| 484 | 484 | u8 intr, |
| 485 | 485 | struct mthca_eq *eq) |
| 486 | 486 | { |
| 487 | − int npages = (nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / | |
| 488 | − PAGE_SIZE; | |
| 487 | + int npages; | |
| 489 | 488 | u64 *dma_list = NULL; |
| 490 | 489 | dma_addr_t t; |
| 491 | 490 | struct mthca_mailbox *mailbox; |
| @@ -496,6 +495,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, · 4 unmodified lines | ||
| 496 | 495 | |
| 497 | 496 | eq->dev = dev; |
| 498 | 497 | eq->nent = roundup_pow_of_two(max(nent, 2)); |
| 498 | + npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE; | |
| 499 | 499 | |
| 500 | 500 | eq->page_list = kmalloc(npages * sizeof *eq->page_list, |
| 501 | 501 | GFP_KERNEL); |
| @@ -261,6 +261,10 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) · 260 unmodified lines | ||
| 261 | 261 | } |
| 262 | 262 | |
| 263 | 263 | err = mthca_dev_lim(mdev, &dev_lim); |
| 264 | + if (err) { | |
| 265 | + mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n"); | |
| 266 | + goto err_disable; | |
| 267 | + } | |
| 264 | 268 | |
| 265 | 269 | profile = default_profile; |
| 266 | 270 | profile.num_uar = dev_lim.uar_size / PAGE_SIZE; |
| @@ -111,7 +111,8 @@ static int find_mgm(struct mthca_dev *dev, · 110 unmodified lines | ||
| 111 | 111 | goto out; |
| 112 | 112 | if (status) { |
| 113 | 113 | mthca_err(dev, "READ_MGM returned status %02x\n", status); |
| 114 | − return -EINVAL; | |
| 114 | + err = -EINVAL; | |
| 115 | + goto out; | |
| 115 | 116 | } |
| 116 | 117 | |
| 117 | 118 | if (!memcmp(mgm->gid, zero_gid, 16)) { |
| @@ -126,7 +127,7 @@ static int find_mgm(struct mthca_dev *dev, · 8 unmodified lines | ||
| 126 | 127 | goto out; |
| 127 | 128 | |
| 128 | 129 | *prev = *index; |
| 129 | − *index = be32_to_cpu(mgm->next_gid_index) >> 5; | |
| 130 | + *index = be32_to_cpu(mgm->next_gid_index) >> 6; | |
| 130 | 131 | } while (*index); |
| 131 | 132 | |
| 132 | 133 | *index = -1; |
| @@ -153,8 +154,10 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 20 unmodified lines | ||
| 153 | 154 | return PTR_ERR(mailbox); |
| 154 | 155 | mgm = mailbox->buf; |
| 155 | 156 | |
| 156 | − if (down_interruptible(&dev->mcg_table.sem)) | |
| 157 | − return -EINTR; | |
| 157 | + if (down_interruptible(&dev->mcg_table.sem)) { | |
| 158 | + err = -EINTR; | |
| 159 | + goto err_sem; | |
| 160 | + } | |
| 158 | 161 | |
| 159 | 162 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
| 160 | 163 | if (err) |
| @@ -181,9 +184,8 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 20 unmodified lines | ||
| 181 | 184 | err = -EINVAL; |
| 182 | 185 | goto out; |
| 183 | 186 | } |
| 184 | − | |
| 187 | + memset(mgm, 0, sizeof *mgm); | |
| 185 | 188 | memcpy(mgm->gid, gid->raw, 16); |
| 186 | − mgm->next_gid_index = 0; | |
| 187 | 189 | } |
| 188 | 190 | |
| 189 | 191 | for (i = 0; i < MTHCA_QP_PER_MGM; ++i) |
| @@ -209,6 +211,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 19 unmodified lines | ||
| 209 | 211 | if (status) { |
| 210 | 212 | mthca_err(dev, "WRITE_MGM returned status %02x\n", status); |
| 211 | 213 | err = -EINVAL; |
| 214 | + goto out; | |
| 212 | 215 | } |
| 213 | 216 | |
| 214 | 217 | if (!link) |
| @@ -223,7 +226,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 8 unmodified lines | ||
| 223 | 226 | goto out; |
| 224 | 227 | } |
| 225 | 228 | |
| 226 | − mgm->next_gid_index = cpu_to_be32(index << 5); | |
| 229 | + mgm->next_gid_index = cpu_to_be32(index << 6); | |
| 227 | 230 | |
| 228 | 231 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
| 229 | 232 | if (err) |
| @@ -234,7 +237,12 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 4 unmodified lines | ||
| 234 | 237 | } |
| 235 | 238 | |
| 236 | 239 | out: |
| 240 | + if (err && link && index != -1) { | |
| 241 | + BUG_ON(index < dev->limits.num_mgms); | |
| 242 | + mthca_free(&dev->mcg_table.alloc, index); | |
| 243 | + } | |
| 237 | 244 | up(&dev->mcg_table.sem); |
| 245 | + err_sem: | |
| 238 | 246 | mthca_free_mailbox(dev, mailbox); |
| 239 | 247 | return err; |
| 240 | 248 | } |
| @@ -255,8 +263,10 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 14 unmodified lines | ||
| 255 | 263 | return PTR_ERR(mailbox); |
| 256 | 264 | mgm = mailbox->buf; |
| 257 | 265 | |
| 258 | − if (down_interruptible(&dev->mcg_table.sem)) | |
| 259 | − return -EINTR; | |
| 266 | + if (down_interruptible(&dev->mcg_table.sem)) { | |
| 267 | + err = -EINTR; | |
| 268 | + goto err_sem; | |
| 269 | + } | |
| 260 | 270 | |
| 261 | 271 | err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); |
| 262 | 272 | if (err) |
| @@ -305,13 +315,11 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 42 unmodified lines | ||
| 305 | 315 | if (i != 1) |
| 306 | 316 | goto out; |
| 307 | 317 | |
| 308 | − goto out; | |
| 309 | − | |
| 310 | 318 | if (prev == -1) { |
| 311 | 319 | /* Remove entry from MGM */ |
| 312 | − if (be32_to_cpu(mgm->next_gid_index) >> 5) { | |
| 313 | − err = mthca_READ_MGM(dev, | |
| 314 | − be32_to_cpu(mgm->next_gid_index) >> 5, | |
| 320 | + int amgm_index_to_free = be32_to_cpu(mgm->next_gid_index) >> 6; | |
| 321 | + if (amgm_index_to_free) { | |
| 322 | + err = mthca_READ_MGM(dev, amgm_index_to_free, | |
| 315 | 323 | mailbox, &status); |
| 316 | 324 | if (err) |
| 317 | 325 | goto out; |
| @@ -332,9 +340,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 14 unmodified lines | ||
| 332 | 340 | err = -EINVAL; |
| 333 | 341 | goto out; |
| 334 | 342 | } |
| 343 | + if (amgm_index_to_free) { | |
| 344 | + BUG_ON(amgm_index_to_free < dev->limits.num_mgms); | |
| 345 | + mthca_free(&dev->mcg_table.alloc, amgm_index_to_free); | |
| 346 | + } | |
| 335 | 347 | } else { |
| 336 | 348 | /* Remove entry from AMGM */ |
| 337 | − index = be32_to_cpu(mgm->next_gid_index) >> 5; | |
| 349 | + int curr_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; | |
| 338 | 350 | err = mthca_READ_MGM(dev, prev, mailbox, &status); |
| 339 | 351 | if (err) |
| 340 | 352 | goto out; |
| @@ -344,7 +356,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 3 unmodified lines | ||
| 344 | 356 | goto out; |
| 345 | 357 | } |
| 346 | 358 | |
| 347 | − mgm->next_gid_index = cpu_to_be32(index << 5); | |
| 359 | + mgm->next_gid_index = cpu_to_be32(curr_next_index << 6); | |
| 348 | 360 | |
| 349 | 361 | err = mthca_WRITE_MGM(dev, prev, mailbox, &status); |
| 350 | 362 | if (err) |
| @@ -354,10 +366,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 3 unmodified lines | ||
| 354 | 366 | err = -EINVAL; |
| 355 | 367 | goto out; |
| 356 | 368 | } |
| 369 | + BUG_ON(index < dev->limits.num_mgms); | |
| 370 | + mthca_free(&dev->mcg_table.alloc, index); | |
| 357 | 371 | } |
| 358 | 372 | |
| 359 | 373 | out: |
| 360 | 374 | up(&dev->mcg_table.sem); |
| 375 | + err_sem: | |
| 361 | 376 | mthca_free_mailbox(dev, mailbox); |
| 362 | 377 | return err; |
| 363 | 378 | } |
| @@ -365,11 +380,12 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) · 1 unmodified line | ||
| 365 | 380 | int __devinit mthca_init_mcg_table(struct mthca_dev *dev) |
| 366 | 381 | { |
| 367 | 382 | int err; |
| 383 | + int table_size = dev->limits.num_mgms + dev->limits.num_amgms; | |
| 368 | 384 | |
| 369 | 385 | err = mthca_alloc_init(&dev->mcg_table.alloc, |
| 370 | − dev->limits.num_amgms, | |
| 371 | − dev->limits.num_amgms - 1, | |
| 372 | − 0); | |
| 386 | + table_size, | |
| 387 | + table_size - 1, | |
| 388 | + dev->limits.num_mgms); | |
| 373 | 389 | if (err) |
| 374 | 390 | return err; |
| 375 | 391 | |
| @@ -233,7 +233,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj) · 232 unmodified lines | ||
| 233 | 233 | for (i = 0; i < chunk->npages; ++i) { |
| 234 | 234 | if (chunk->mem[i].length >= offset) { |
| 235 | 235 | page = chunk->mem[i].page; |
| 236 | − break; | |
| 236 | + goto out; | |
| 237 | 237 | } |
| 238 | 238 | offset -= chunk->mem[i].length; |
| 239 | 239 | } |
| @@ -485,6 +485,8 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, · 245 unmodified lines | ||
| 485 | 485 | put_page(db_tab->page[i].mem.page); |
| 486 | 486 | } |
| 487 | 487 | } |
| 488 | + | |
| 489 | + kfree(db_tab); | |
| 488 | 490 | } |
| 489 | 491 | |
| 490 | 492 | int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, |
| @@ -383,12 +383,10 @@ static const struct { · 382 unmodified lines | ||
| 383 | 383 | [UC] = (IB_QP_CUR_STATE | |
| 384 | 384 | IB_QP_ALT_PATH | |
| 385 | 385 | IB_QP_ACCESS_FLAGS | |
| 386 | − IB_QP_PKEY_INDEX | | |
| 387 | 386 | IB_QP_PATH_MIG_STATE), |
| 388 | 387 | [RC] = (IB_QP_CUR_STATE | |
| 389 | 388 | IB_QP_ALT_PATH | |
| 390 | 389 | IB_QP_ACCESS_FLAGS | |
| 391 | − IB_QP_PKEY_INDEX | | |
| 392 | 390 | IB_QP_MIN_RNR_TIMER | |
| 393 | 391 | IB_QP_PATH_MIG_STATE), |
| 394 | 392 | [MLX] = (IB_QP_CUR_STATE | |
| @@ -476,9 +474,8 @@ static const struct { · 81 unmodified lines | ||
| 476 | 474 | .opt_param = { |
| 477 | 475 | [UD] = (IB_QP_CUR_STATE | |
| 478 | 476 | IB_QP_QKEY), |
| 479 | − [UC] = IB_QP_CUR_STATE, | |
| 480 | − [RC] = (IB_QP_CUR_STATE | | |
| 481 | − IB_QP_MIN_RNR_TIMER), | |
| 477 | + [UC] = (IB_QP_CUR_STATE | | |
| 478 | + IB_QP_ACCESS_FLAGS), | |
| 482 | 479 | [MLX] = (IB_QP_CUR_STATE | |
| 483 | 480 | IB_QP_QKEY), |
| 484 | 481 | } |
| @@ -522,6 +519,55 @@ static void init_port(struct mthca_dev *dev, int port) · 37 unmodified lines | ||
| 522 | 519 | mthca_warn(dev, "INIT_IB returned status %02x.\n", status); |
| 523 | 520 | } |
| 524 | 521 | |
| 522 | +static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, | |
| 523 | + int attr_mask) | |
| 524 | +{ | |
| 525 | + u8 dest_rd_atomic; | |
| 526 | + u32 access_flags; | |
| 527 | + u32 hw_access_flags = 0; | |
| 528 | + | |
| 529 | + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) | |
| 530 | + dest_rd_atomic = attr->max_dest_rd_atomic; | |
| 531 | + else | |
| 532 | + dest_rd_atomic = qp->resp_depth; | |
| 533 | + | |
| 534 | + if (attr_mask & IB_QP_ACCESS_FLAGS) | |
| 535 | + access_flags = attr->qp_access_flags; | |
| 536 | + else | |
| 537 | + access_flags = qp->atomic_rd_en; | |
| 538 | + | |
| 539 | + if (!dest_rd_atomic) | |
| 540 | + access_flags &= IB_ACCESS_REMOTE_WRITE; | |
| 541 | + | |
| 542 | + if (access_flags & IB_ACCESS_REMOTE_READ) | |
| 543 | + hw_access_flags |= MTHCA_QP_BIT_RRE; | |
| 544 | + if (access_flags & IB_ACCESS_REMOTE_ATOMIC) | |
| 545 | + hw_access_flags |= MTHCA_QP_BIT_RAE; | |
| 546 | + if (access_flags & IB_ACCESS_REMOTE_WRITE) | |
| 547 | + hw_access_flags |= MTHCA_QP_BIT_RWE; | |
| 548 | + | |
| 549 | + return cpu_to_be32(hw_access_flags); | |
| 550 | +} | |
| 551 | + | |
| 552 | +static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) | |
| 553 | +{ | |
| 554 | + path->g_mylmc = ah->src_path_bits & 0x7f; | |
| 555 | + path->rlid = cpu_to_be16(ah->dlid); | |
| 556 | + path->static_rate = !!ah->static_rate; | |
| 557 | + | |
| 558 | + if (ah->ah_flags & IB_AH_GRH) { | |
| 559 | + path->g_mylmc |= 1 << 7; | |
| 560 | + path->mgid_index = ah->grh.sgid_index; | |
| 561 | + path->hop_limit = ah->grh.hop_limit; | |
| 562 | + path->sl_tclass_flowlabel = | |
| 563 | + cpu_to_be32((ah->sl << 28) | | |
| 564 | + (ah->grh.traffic_class << 20) | | |
| 565 | + (ah->grh.flow_label)); | |
| 566 | + memcpy(path->rgid, ah->grh.dgid.raw, 16); | |
| 567 | + } else | |
| 568 | + path->sl_tclass_flowlabel = cpu_to_be32(ah->sl << 28); | |
| 569 | +} | |
| 570 | + | |
| 525 | 571 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) |
| 526 | 572 | { |
| 527 | 573 | struct mthca_dev *dev = to_mdev(ibqp->device); |
| @@ -591,6 +637,26 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 63 unmodified lines | ||
| 591 | 637 | return -EINVAL; |
| 592 | 638 | } |
| 593 | 639 | |
| 640 | + if ((attr_mask & IB_QP_PORT) && | |
| 641 | + (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) { | |
| 642 | + mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num); | |
| 643 | + return -EINVAL; | |
| 644 | + } | |
| 645 | + | |
| 646 | + if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && | |
| 647 | + attr->max_rd_atomic > dev->limits.max_qp_init_rdma) { | |
| 648 | + mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n", | |
| 649 | + attr->max_rd_atomic, dev->limits.max_qp_init_rdma); | |
| 650 | + return -EINVAL; | |
| 651 | + } | |
| 652 | + | |
| 653 | + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && | |
| 654 | + attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) { | |
| 655 | + mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n", | |
| 656 | + attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift); | |
| 657 | + return -EINVAL; | |
| 658 | + } | |
| 659 | + | |
| 594 | 660 | mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); |
| 595 | 661 | if (IS_ERR(mailbox)) |
| 596 | 662 | return PTR_ERR(mailbox); |
| @@ -665,28 +731,14 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 68 unmodified lines | ||
| 665 | 731 | } |
| 666 | 732 | |
| 667 | 733 | if (attr_mask & IB_QP_RNR_RETRY) { |
| 668 | − qp_context->pri_path.rnr_retry = attr->rnr_retry << 5; | |
| 669 | − qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY); | |
| 734 | + qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry = | |
| 735 | + attr->rnr_retry << 5; | |
| 736 | + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY | | |
| 737 | + MTHCA_QP_OPTPAR_ALT_RNR_RETRY); | |
| 670 | 738 | } |
| 671 | 739 | |
| 672 | 740 | if (attr_mask & IB_QP_AV) { |
| 673 | − qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; | |
| 674 | − qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); | |
| 675 | − qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate; | |
| 676 | − if (attr->ah_attr.ah_flags & IB_AH_GRH) { | |
| 677 | − qp_context->pri_path.g_mylmc |= 1 << 7; | |
| 678 | − qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; | |
| 679 | − qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit; | |
| 680 | − qp_context->pri_path.sl_tclass_flowlabel = | |
| 681 | − cpu_to_be32((attr->ah_attr.sl << 28) | | |
| 682 | − (attr->ah_attr.grh.traffic_class << 20) | | |
| 683 | − (attr->ah_attr.grh.flow_label)); | |
| 684 | − memcpy(qp_context->pri_path.rgid, | |
| 685 | − attr->ah_attr.grh.dgid.raw, 16); | |
| 686 | − } else { | |
| 687 | − qp_context->pri_path.sl_tclass_flowlabel = | |
| 688 | − cpu_to_be32(attr->ah_attr.sl << 28); | |
| 689 | − } | |
| 741 | + mthca_path_set(&attr->ah_attr, &qp_context->pri_path); | |
| 690 | 742 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); |
| 691 | 743 | } |
| 692 | 744 | |
| @@ -695,7 +747,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 2 unmodified lines | ||
| 695 | 747 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); |
| 696 | 748 | } |
| 697 | 749 | |
| 698 | − /* XXX alt_path */ | |
| 750 | + if (attr_mask & IB_QP_ALT_PATH) { | |
| 751 | + if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) { | |
| 752 | + mthca_dbg(dev, "Alternate port number (%u) is invalid\n", | |
| 753 | + attr->alt_port_num); | |
| 754 | + return -EINVAL; | |
| 755 | + } | |
| 756 | + | |
| 757 | + mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path); | |
| 758 | + qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | | |
| 759 | + attr->alt_port_num << 24); | |
| 760 | + qp_context->alt_path.ackto = attr->alt_timeout << 3; | |
| 761 | + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH); | |
| 762 | + } | |
| 699 | 763 | |
| 700 | 764 | /* leave rdd as 0 */ |
| 701 | 765 | qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); |
| @@ -703,9 +767,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 1 unmodified line | ||
| 703 | 767 | qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey); |
| 704 | 768 | qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) | |
| 705 | 769 | (MTHCA_FLIGHT_LIMIT << 24) | |
| 706 | − MTHCA_QP_BIT_SRE | | |
| 707 | − MTHCA_QP_BIT_SWE | | |
| 708 | − MTHCA_QP_BIT_SAE); | |
| 770 | + MTHCA_QP_BIT_SWE); | |
| 709 | 771 | if (qp->sq_policy == IB_SIGNAL_ALL_WR) |
| 710 | 772 | qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC); |
| 711 | 773 | if (attr_mask & IB_QP_RETRY_CNT) { |
| @@ -714,9 +776,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 2 unmodified lines | ||
| 714 | 776 | } |
| 715 | 777 | |
| 716 | 778 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { |
| 717 | − qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ? | |
| 718 | − ffs(attr->max_rd_atomic) - 1 : 0, | |
| 719 | − 7) << 21); | |
| 779 | + if (attr->max_rd_atomic) { | |
| 780 | + qp_context->params1 |= | |
| 781 | + cpu_to_be32(MTHCA_QP_BIT_SRE | | |
| 782 | + MTHCA_QP_BIT_SAE); | |
| 783 | + qp_context->params1 |= | |
| 784 | + cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21); | |
| 785 | + } | |
| 720 | 786 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); |
| 721 | 787 | } |
| 722 | 788 | |
| @@ -729,71 +795,19 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 6 unmodified lines | ||
| 729 | 795 | qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index); |
| 730 | 796 | } |
| 731 | 797 | |
| 732 | − if (attr_mask & IB_QP_ACCESS_FLAGS) { | |
| 733 | − qp_context->params2 |= | |
| 734 | − cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ? | |
| 735 | − MTHCA_QP_BIT_RWE : 0); | |
| 736 | − | |
| 737 | − /* | |
| 738 | − * Only enable RDMA reads and atomics if we have | |
| 739 | − * responder resources set to a non-zero value. | |
| 740 | − */ | |
| 741 | − if (qp->resp_depth) { | |
| 742 | − qp_context->params2 |= | |
| 743 | − cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ? | |
| 744 | − MTHCA_QP_BIT_RRE : 0); | |
| 745 | − qp_context->params2 |= | |
| 746 | − cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ? | |
| 747 | − MTHCA_QP_BIT_RAE : 0); | |
| 748 | − } | |
| 749 | − | |
| 750 | − qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | | |
| 751 | − MTHCA_QP_OPTPAR_RRE | | |
| 752 | − MTHCA_QP_OPTPAR_RAE); | |
| 753 | − | |
| 754 | − qp->atomic_rd_en = attr->qp_access_flags; | |
| 755 | − } | |
| 756 | − | |
| 757 | 798 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { |
| 758 | − u8 rra_max; | |
| 759 | − | |
| 760 | − if (qp->resp_depth && !attr->max_dest_rd_atomic) { | |
| 761 | − /* | |
| 762 | − * Lowering our responder resources to zero. | |
| 763 | − * Turn off reads RDMA and atomics as responder. | |
| 764 | − * (RRE/RAE in params2 already zero) | |
| 765 | − */ | |
| 766 | − qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | | |
| 767 | − MTHCA_QP_OPTPAR_RAE); | |
| 768 | − } | |
| 769 | − | |
| 770 | − if (!qp->resp_depth && attr->max_dest_rd_atomic) { | |
| 771 | − /* | |
| 772 | − * Increasing our responder resources from | |
| 773 | − * zero. Turn on RDMA reads and atomics as | |
| 774 | − * appropriate. | |
| 775 | − */ | |
| 799 | + if (attr->max_dest_rd_atomic) | |
| 776 | 800 | qp_context->params2 |= |
| 777 | − cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ? | |
| 778 | − MTHCA_QP_BIT_RRE : 0); | |
| 779 | − qp_context->params2 |= | |
| 780 | − cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ? | |
| 781 | − MTHCA_QP_BIT_RAE : 0); | |
| 782 | − | |
| 783 | − qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | | |
| 784 | − MTHCA_QP_OPTPAR_RAE); | |
| 785 | − } | |
| 801 | + cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21); | |
| 786 | 802 | |
| 787 | − for (rra_max = 0; | |
| 788 | − 1 << rra_max < attr->max_dest_rd_atomic && | |
| 789 | − rra_max < dev->qp_table.rdb_shift; | |
| 790 | − ++rra_max) | |
| 791 | − ; /* nothing */ | |
| 792 | − | |
| 793 | − qp_context->params2 |= cpu_to_be32(rra_max << 21); | |
| 794 | 803 | qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); |
| 804 | + } | |
| 795 | 805 | |
| 796 | − qp->resp_depth = attr->max_dest_rd_atomic; | |
| 806 | + if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { | |
| 807 | + qp_context->params2 |= get_hw_access_flags(qp, attr, attr_mask); | |
| 808 | + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | | |
| 809 | + MTHCA_QP_OPTPAR_RRE | | |
| 810 | + MTHCA_QP_OPTPAR_RAE); | |
| 797 | 811 | } |
| 798 | 812 | |
| 799 | 813 | qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); |
| @@ -835,8 +849,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 35 unmodified lines | ||
| 835 | 849 | err = -EINVAL; |
| 836 | 850 | } |
| 837 | 851 | |
| 838 | − if (!err) | |
| 852 | + if (!err) { | |
| 839 | 853 | qp->state = new_state; |
| 854 | + if (attr_mask & IB_QP_ACCESS_FLAGS) | |
| 855 | + qp->atomic_rd_en = attr->qp_access_flags; | |
| 856 | + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) | |
| 857 | + qp->resp_depth = attr->max_dest_rd_atomic; | |
| 858 | + } | |
| 840 | 859 | |
| 841 | 860 | mthca_free_mailbox(dev, mailbox); |
| 842 | 861 | |
| @@ -885,18 +904,13 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) · 42 unmodified lines | ||
| 885 | 904 | return err; |
| 886 | 905 | } |
| 887 | 906 | |
| 888 | −static void mthca_adjust_qp_caps(struct mthca_dev *dev, | |
| 889 | − struct mthca_pd *pd, | |
| 890 | − struct mthca_qp *qp) | |
| 907 | +static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz) | |
| 891 | 908 | { |
| 892 | − int max_data_size; | |
| 893 | − | |
| 894 | 909 | /* |
| 895 | 910 | * Calculate the maximum size of WQE s/g segments, excluding |
| 896 | 911 | * the next segment and other non-data segments. |
| 897 | 912 | */ |
| 898 | − max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - | |
| 899 | − sizeof (struct mthca_next_seg); | |
| 913 | + int max_data_size = desc_sz - sizeof (struct mthca_next_seg); | |
| 900 | 914 | |
| 901 | 915 | switch (qp->transport) { |
| 902 | 916 | case MLX: |
| @@ -915,11 +929,24 @@ static void mthca_adjust_qp_caps(struct mthca_dev *dev, · 12 unmodified lines | ||
| 915 | 929 | break; |
| 916 | 930 | } |
| 917 | 931 | |
| 932 | + return max_data_size; | |
| 933 | +} | |
| 934 | + | |
| 935 | +static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size) | |
| 936 | +{ | |
| 918 | 937 | /* We don't support inline data for kernel QPs (yet). */ |
| 919 | − if (!pd->ibpd.uobject) | |
| 920 | − qp->max_inline_data = 0; | |
| 921 | − else | |
| 922 | − qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; | |
| 938 | + return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0; | |
| 939 | +} | |
| 940 | + | |
| 941 | +static void mthca_adjust_qp_caps(struct mthca_dev *dev, | |
| 942 | + struct mthca_pd *pd, | |
| 943 | + struct mthca_qp *qp) | |
| 944 | +{ | |
| 945 | + int max_data_size = mthca_max_data_size(dev, qp, | |
| 946 | + min(dev->limits.max_desc_sz, | |
| 947 | + 1 << qp->sq.wqe_shift)); | |
| 948 | + | |
| 949 | + qp->max_inline_data = mthca_max_inline_data(pd, max_data_size); | |
| 923 | 950 | |
| 924 | 951 | qp->sq.max_gs = min_t(int, dev->limits.max_sg, |
| 925 | 952 | max_data_size / sizeof (struct mthca_data_seg)); |
| @@ -1186,13 +1213,23 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, · 260 unmodified lines | ||
| 1186 | 1213 | } |
| 1187 | 1214 | |
| 1188 | 1215 | static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, |
| 1189 | − struct mthca_qp *qp) | |
| 1216 | + struct mthca_pd *pd, struct mthca_qp *qp) | |
| 1190 | 1217 | { |
| 1218 | + int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz); | |
| 1219 | + | |
| 1191 | 1220 | /* Sanity check QP size before proceeding */ |
| 1192 | − if (cap->max_send_wr > dev->limits.max_wqes || | |
| 1193 | − cap->max_recv_wr > dev->limits.max_wqes || | |
| 1194 | − cap->max_send_sge > dev->limits.max_sg || | |
| 1195 | − cap->max_recv_sge > dev->limits.max_sg) | |
| 1221 | + if (cap->max_send_wr > dev->limits.max_wqes || | |
| 1222 | + cap->max_recv_wr > dev->limits.max_wqes || | |
| 1223 | + cap->max_send_sge > dev->limits.max_sg || | |
| 1224 | + cap->max_recv_sge > dev->limits.max_sg || | |
| 1225 | + cap->max_inline_data > mthca_max_inline_data(pd, max_data_size)) | |
| 1226 | + return -EINVAL; | |
| 1227 | + | |
| 1228 | + /* | |
| 1229 | + * For MLX transport we need 2 extra S/G entries: | |
| 1230 | + * one for the header and one for the checksum at the end | |
| 1231 | + */ | |
| 1232 | + if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg) | |
| 1196 | 1233 | return -EINVAL; |
| 1197 | 1234 | |
| 1198 | 1235 | if (mthca_is_memfree(dev)) { |
| @@ -1211,14 +1248,6 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, · 12 unmodified lines | ||
| 1211 | 1248 | MTHCA_INLINE_CHUNK_SIZE) / |
| 1212 | 1249 | sizeof (struct mthca_data_seg)); |
| 1213 | 1250 | |
| 1214 | − /* | |
| 1215 | − * For MLX transport we need 2 extra S/G entries: | |
| 1216 | − * one for the header and one for the checksum at the end | |
| 1217 | − */ | |
| 1218 | − if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) || | |
| 1219 | − qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg) | |
| 1220 | − return -EINVAL; | |
| 1221 | − | |
| 1222 | 1251 | return 0; |
| 1223 | 1252 | } |
| 1224 | 1253 | |
| @@ -1233,7 +1262,7 @@ int mthca_alloc_qp(struct mthca_dev *dev, · 8 unmodified lines | ||
| 1233 | 1262 | { |
| 1234 | 1263 | int err; |
| 1235 | 1264 | |
| 1236 | − err = mthca_set_qp_size(dev, cap, qp); | |
| 1265 | + err = mthca_set_qp_size(dev, cap, pd, qp); | |
| 1237 | 1266 | if (err) |
| 1238 | 1267 | return err; |
| 1239 | 1268 | |
| @@ -1276,7 +1305,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev, · 36 unmodified lines | ||
| 1276 | 1305 | u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; |
| 1277 | 1306 | int err; |
| 1278 | 1307 | |
| 1279 | − err = mthca_set_qp_size(dev, cap, &sqp->qp); | |
| 1308 | + err = mthca_set_qp_size(dev, cap, pd, &sqp->qp); | |
| 1280 | 1309 | if (err) |
| 1281 | 1310 | return err; |
| 1282 | 1311 | |
| @@ -201,7 +201,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, · 200 unmodified lines | ||
| 201 | 201 | if (mthca_is_memfree(dev)) |
| 202 | 202 | srq->max = roundup_pow_of_two(srq->max + 1); |
| 203 | 203 | |
| 204 | − ds = min(64UL, | |
| 204 | + ds = max(64UL, | |
| 205 | 205 | roundup_pow_of_two(sizeof (struct mthca_next_seg) + |
| 206 | 206 | srq->max_gs * sizeof (struct mthca_data_seg))); |
| 207 | 207 | srq->wqe_shift = long_log2(ds); |