Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB: Return qp pointer as part of ib_wc

struct ib_wc currently only includes the local QP number: this matches
the IB spec, but seems mostly useless. The following patch replaces
this with the pointer to qp itself, and updates all low level drivers
and all users.

This has the following advantages:
- Ability to get a per-qp context through wc->qp->qp_context
- Existing drivers already have the qp pointer ready in poll cq, so
this change actually saves a tiny bit (extra memory read) on data path
(for ehca it would actually be expensive to find the QP pointer when
polling a CQ, but ehca does not support SRQ so we can leave wc->qp as
NULL for ehca)
- Users that need the QP number can still get it through wc->qp->qp_num

Use case:

In IPoIB connected mode code, I have a common CQ shared by multiple
QPs. To track connection usage, I need a way to get at some per-QP
context upon the completion, and I would like to avoid allocating
context object per work request just to stick a QP pointer into it.
With this code, I can just use wc->qp->qp_context.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by

Michael S. Tsirkin and committed by
Roland Dreier
062dbb69 459d6e2a

+28 -25
+7 -4
drivers/infiniband/core/mad.c
··· 642 642 spin_unlock_irqrestore(&qp_info->snoop_lock, flags); 643 643 } 644 644 645 - static void build_smp_wc(u64 wr_id, u16 slid, u16 pkey_index, u8 port_num, 645 + static void build_smp_wc(struct ib_qp *qp, 646 + u64 wr_id, u16 slid, u16 pkey_index, u8 port_num, 646 647 struct ib_wc *wc) 647 648 { 648 649 memset(wc, 0, sizeof *wc); ··· 653 652 wc->pkey_index = pkey_index; 654 653 wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh); 655 654 wc->src_qp = IB_QP0; 656 - wc->qp_num = IB_QP0; 655 + wc->qp = qp; 657 656 wc->slid = slid; 658 657 wc->sl = 0; 659 658 wc->dlid_path_bits = 0; ··· 714 713 goto out; 715 714 } 716 715 717 - build_smp_wc(send_wr->wr_id, be16_to_cpu(smp->dr_slid), 716 + build_smp_wc(mad_agent_priv->agent.qp, 717 + send_wr->wr_id, be16_to_cpu(smp->dr_slid), 718 718 send_wr->wr.ud.pkey_index, 719 719 send_wr->wr.ud.port_num, &mad_wc); 720 720 ··· 2357 2355 * Defined behavior is to complete response 2358 2356 * before request 2359 2357 */ 2360 - build_smp_wc((unsigned long) local->mad_send_wr, 2358 + build_smp_wc(recv_mad_agent->agent.qp, 2359 + (unsigned long) local->mad_send_wr, 2361 2360 be16_to_cpu(IB_LID_PERMISSIVE), 2362 2361 0, recv_mad_agent->agent.port_num, &wc); 2363 2362
+1 -1
drivers/infiniband/core/uverbs_cmd.c
··· 933 933 resp->wc[i].vendor_err = wc[i].vendor_err; 934 934 resp->wc[i].byte_len = wc[i].byte_len; 935 935 resp->wc[i].imm_data = (__u32 __force) wc[i].imm_data; 936 - resp->wc[i].qp_num = wc[i].qp_num; 936 + resp->wc[i].qp_num = wc[i].qp->qp_num; 937 937 resp->wc[i].src_qp = wc[i].src_qp; 938 938 resp->wc[i].wc_flags = wc[i].wc_flags; 939 939 resp->wc[i].pkey_index = wc[i].pkey_index;
+1 -1
drivers/infiniband/hw/amso1100/c2_cq.c
··· 153 153 154 154 entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce)); 155 155 entry->wr_id = ce->hdr.context; 156 - entry->qp_num = ce->handle; 156 + entry->qp = &qp->ibqp; 157 157 entry->wc_flags = 0; 158 158 entry->slid = 0; 159 159 entry->sl = 0;
+1 -1
drivers/infiniband/hw/ehca/ehca_reqs.c
··· 579 579 } else 580 580 wc->status = IB_WC_SUCCESS; 581 581 582 - wc->qp_num = cqe->local_qp_number; 582 + wc->qp = NULL; 583 583 wc->byte_len = cqe->nr_bytes_transferred; 584 584 wc->pkey_index = cqe->pkey_index; 585 585 wc->slid = cqe->rlid;
+1 -1
drivers/infiniband/hw/ipath/ipath_qp.c
··· 379 379 wc.vendor_err = 0; 380 380 wc.byte_len = 0; 381 381 wc.imm_data = 0; 382 - wc.qp_num = qp->ibqp.qp_num; 382 + wc.qp = &qp->ibqp; 383 383 wc.src_qp = 0; 384 384 wc.wc_flags = 0; 385 385 wc.pkey_index = 0;
+4 -4
drivers/infiniband/hw/ipath/ipath_rc.c
··· 702 702 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 703 703 wc->vendor_err = 0; 704 704 wc->byte_len = 0; 705 - wc->qp_num = qp->ibqp.qp_num; 705 + wc->qp = &qp->ibqp; 706 706 wc->src_qp = qp->remote_qpn; 707 707 wc->pkey_index = 0; 708 708 wc->slid = qp->remote_ah_attr.dlid; ··· 836 836 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 837 837 wc.vendor_err = 0; 838 838 wc.byte_len = wqe->length; 839 - wc.qp_num = qp->ibqp.qp_num; 839 + wc.qp = &qp->ibqp; 840 840 wc.src_qp = qp->remote_qpn; 841 841 wc.pkey_index = 0; 842 842 wc.slid = qp->remote_ah_attr.dlid; ··· 951 951 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 952 952 wc.vendor_err = 0; 953 953 wc.byte_len = 0; 954 - wc.qp_num = qp->ibqp.qp_num; 954 + wc.qp = &qp->ibqp; 955 955 wc.src_qp = qp->remote_qpn; 956 956 wc.pkey_index = 0; 957 957 wc.slid = qp->remote_ah_attr.dlid; ··· 1511 1511 wc.status = IB_WC_SUCCESS; 1512 1512 wc.opcode = IB_WC_RECV; 1513 1513 wc.vendor_err = 0; 1514 - wc.qp_num = qp->ibqp.qp_num; 1514 + wc.qp = &qp->ibqp; 1515 1515 wc.src_qp = qp->remote_qpn; 1516 1516 wc.pkey_index = 0; 1517 1517 wc.slid = qp->remote_ah_attr.dlid;
+4 -4
drivers/infiniband/hw/ipath/ipath_ruc.c
··· 137 137 wc.vendor_err = 0; 138 138 wc.byte_len = 0; 139 139 wc.imm_data = 0; 140 - wc.qp_num = qp->ibqp.qp_num; 140 + wc.qp = &qp->ibqp; 141 141 wc.src_qp = 0; 142 142 wc.wc_flags = 0; 143 143 wc.pkey_index = 0; ··· 336 336 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 337 337 wc.vendor_err = 0; 338 338 wc.byte_len = 0; 339 - wc.qp_num = sqp->ibqp.qp_num; 339 + wc.qp = &sqp->ibqp; 340 340 wc.src_qp = sqp->remote_qpn; 341 341 wc.pkey_index = 0; 342 342 wc.slid = sqp->remote_ah_attr.dlid; ··· 426 426 wc.status = IB_WC_SUCCESS; 427 427 wc.vendor_err = 0; 428 428 wc.byte_len = wqe->length; 429 - wc.qp_num = qp->ibqp.qp_num; 429 + wc.qp = &qp->ibqp; 430 430 wc.src_qp = qp->remote_qpn; 431 431 /* XXX do we know which pkey matched? Only needed for GSI. */ 432 432 wc.pkey_index = 0; ··· 447 447 wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 448 448 wc.vendor_err = 0; 449 449 wc.byte_len = wqe->length; 450 - wc.qp_num = sqp->ibqp.qp_num; 450 + wc.qp = &sqp->ibqp; 451 451 wc.src_qp = 0; 452 452 wc.pkey_index = 0; 453 453 wc.slid = 0;
+2 -2
drivers/infiniband/hw/ipath/ipath_uc.c
··· 49 49 wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; 50 50 wc->vendor_err = 0; 51 51 wc->byte_len = wqe->length; 52 - wc->qp_num = qp->ibqp.qp_num; 52 + wc->qp = &qp->ibqp; 53 53 wc->src_qp = qp->remote_qpn; 54 54 wc->pkey_index = 0; 55 55 wc->slid = qp->remote_ah_attr.dlid; ··· 411 411 wc.status = IB_WC_SUCCESS; 412 412 wc.opcode = IB_WC_RECV; 413 413 wc.vendor_err = 0; 414 - wc.qp_num = qp->ibqp.qp_num; 414 + wc.qp = &qp->ibqp; 415 415 wc.src_qp = qp->remote_qpn; 416 416 wc.pkey_index = 0; 417 417 wc.slid = qp->remote_ah_attr.dlid;
+4 -4
drivers/infiniband/hw/ipath/ipath_ud.c
··· 66 66 wc.vendor_err = 0; 67 67 wc.byte_len = 0; 68 68 wc.imm_data = 0; 69 - wc.qp_num = qp->ibqp.qp_num; 69 + wc.qp = &qp->ibqp; 70 70 wc.src_qp = 0; 71 71 wc.wc_flags = 0; 72 72 wc.pkey_index = 0; ··· 255 255 wc->status = IB_WC_SUCCESS; 256 256 wc->opcode = IB_WC_RECV; 257 257 wc->vendor_err = 0; 258 - wc->qp_num = qp->ibqp.qp_num; 258 + wc->qp = &qp->ibqp; 259 259 wc->src_qp = sqp->ibqp.qp_num; 260 260 /* XXX do we know which pkey matched? Only needed for GSI. */ 261 261 wc->pkey_index = 0; ··· 474 474 wc.vendor_err = 0; 475 475 wc.opcode = IB_WC_SEND; 476 476 wc.byte_len = len; 477 - wc.qp_num = qp->ibqp.qp_num; 477 + wc.qp = &qp->ibqp; 478 478 wc.src_qp = 0; 479 479 wc.wc_flags = 0; 480 480 /* XXX initialize other fields? */ ··· 651 651 wc.status = IB_WC_SUCCESS; 652 652 wc.opcode = IB_WC_RECV; 653 653 wc.vendor_err = 0; 654 - wc.qp_num = qp->ibqp.qp_num; 654 + wc.qp = &qp->ibqp; 655 655 wc.src_qp = src_qp; 656 656 /* XXX do we know which pkey matched? Only needed for GSI. */ 657 657 wc.pkey_index = 0;
+1 -1
drivers/infiniband/hw/mthca/mthca_cmd.c
··· 1854 1854 1855 1855 memset(inbox + 256, 0, 256); 1856 1856 1857 - MTHCA_PUT(inbox, in_wc->qp_num, MAD_IFC_MY_QPN_OFFSET); 1857 + MTHCA_PUT(inbox, in_wc->qp->qp_num, MAD_IFC_MY_QPN_OFFSET); 1858 1858 MTHCA_PUT(inbox, in_wc->src_qp, MAD_IFC_RQPN_OFFSET); 1859 1859 1860 1860 val = in_wc->sl << 4;
+1 -1
drivers/infiniband/hw/mthca/mthca_cq.c
··· 534 534 } 535 535 } 536 536 537 - entry->qp_num = (*cur_qp)->qpn; 537 + entry->qp = &(*cur_qp)->ibqp; 538 538 539 539 if (is_send) { 540 540 wq = &(*cur_qp)->sq;
+1 -1
include/rdma/ib_verbs.h
··· 420 420 enum ib_wc_opcode opcode; 421 421 u32 vendor_err; 422 422 u32 byte_len; 423 + struct ib_qp *qp; 423 424 __be32 imm_data; 424 - u32 qp_num; 425 425 u32 src_qp; 426 426 int wc_flags; 427 427 u16 pkey_index;