> Quoting Michael S. Tsirkin <[EMAIL PROTECTED]>:
> Subject: Re: [PATCH for-2.6.21] mthca: QP reset race fixup
> 
> In hindsight, it was probably better to put qp_context directly in ib_wc
> instead of the qp pointer.
> 
> Then ipoib could set some flag in the structure pointed to by qp_context.
> 
> My guess this would be too big a change for 2.6.21. What do you think?


Here's how a patch to make the use after free fixable for ULPs that do polling
out of interrupt context (e.g. IPoIB with NAPI) would look like.

What do you think?

Warning: untested.

Signed-off-by: Michael S. Tsirkin <[EMAIL PROTECTED]>

---

diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 765589f..4dc769a 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -420,7 +420,8 @@ struct ib_wc {
        enum ib_wc_opcode       opcode;
        u32                     vendor_err;
        u32                     byte_len;
-       struct ib_qp           *qp;
+       void                   *qp_context;
+       u32                     qp_num;
        __be32                  imm_data;
        u32                     src_qp;
        int                     wc_flags;
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 13efd41..7bad7ec 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -653,7 +653,8 @@ static void build_smp_wc(struct ib_qp *qp,
        wc->pkey_index = pkey_index;
        wc->byte_len = sizeof(struct ib_mad) + sizeof(struct ib_grh);
        wc->src_qp = IB_QP0;
-       wc->qp = qp;
+       wc->qp_num = qp->qp_num;
+       wc->qp_context = qp->qp_context;
        wc->slid = slid;
        wc->sl = 0;
        wc->dlid_path_bits = 0;
diff --git a/drivers/infiniband/core/uverbs_cmd.c 
b/drivers/infiniband/core/uverbs_cmd.c
index 4fd75af..b90e4a6 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -935,7 +935,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                resp->wc[i].vendor_err     = wc[i].vendor_err;
                resp->wc[i].byte_len       = wc[i].byte_len;
                resp->wc[i].imm_data       = (__u32 __force) wc[i].imm_data;
-               resp->wc[i].qp_num         = wc[i].qp->qp_num;
+               resp->wc[i].qp_num         = wc[i].qp_num;
                resp->wc[i].src_qp         = wc[i].src_qp;
                resp->wc[i].wc_flags       = wc[i].wc_flags;
                resp->wc[i].pkey_index     = wc[i].pkey_index;
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c 
b/drivers/infiniband/hw/amso1100/c2_cq.c
index 5175c99..835f7ed 100644
--- a/drivers/infiniband/hw/amso1100/c2_cq.c
+++ b/drivers/infiniband/hw/amso1100/c2_cq.c
@@ -153,7 +153,8 @@ static inline int c2_poll_one(struct c2_dev *c2dev,
 
        entry->status = c2_cqe_status_to_openib(c2_wr_get_result(ce));
        entry->wr_id = ce->hdr.context;
-       entry->qp = &qp->ibqp;
+       entry->qp_num = qp->ibqp.qp_num;
+       entry->qp_context = qp->ibqp.qp_context;
        entry->wc_flags = 0;
        entry->slid = 0;
        entry->sl = 0;
diff --git a/drivers/infiniband/hw/ehca/ehca_reqs.c 
b/drivers/infiniband/hw/ehca/ehca_reqs.c
index 08d3f89..9c4e579 100644
--- a/drivers/infiniband/hw/ehca/ehca_reqs.c
+++ b/drivers/infiniband/hw/ehca/ehca_reqs.c
@@ -579,7 +579,8 @@ poll_cq_one_read_cqe:
        } else
                wc->status = IB_WC_SUCCESS;
 
-       wc->qp = NULL;
+       wc->qp_num = cqe->local_qp_number;
+       wc->qp_context = NULL;
        wc->byte_len = cqe->nr_bytes_transferred;
        wc->pkey_index = cqe->pkey_index;
        wc->slid = cqe->rlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c 
b/drivers/infiniband/hw/ipath/ipath_qp.c
index 64f07b1..a00230f 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -379,7 +379,8 @@ void ipath_error_qp(struct ipath_qp *qp, enum ib_wc_status 
err)
        wc.vendor_err = 0;
        wc.byte_len = 0;
        wc.imm_data = 0;
-       wc.qp = &qp->ibqp;
+       wc.qp_num = qp->ibqp.qp_num;
+       wc.qp_context = qp->ibqp.qp_context;
        wc.src_qp = 0;
        wc.wc_flags = 0;
        wc.pkey_index = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c 
b/drivers/infiniband/hw/ipath/ipath_rc.c
index 5ff20cb..74db045 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -702,7 +702,8 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct 
ib_wc *wc)
                wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
                wc->vendor_err = 0;
                wc->byte_len = 0;
-               wc->qp = &qp->ibqp;
+               wc->qp_num = qp->ibqp.qp_num;
+               wc->qp_context = qp->ibqp.qp_context;
                wc->src_qp = qp->remote_qpn;
                wc->pkey_index = 0;
                wc->slid = qp->remote_ah_attr.dlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c 
b/drivers/infiniband/hw/ipath/ipath_ruc.c
index e86cb17..ffe70ed 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -137,7 +137,8 @@ bad_lkey:
        wc.vendor_err = 0;
        wc.byte_len = 0;
        wc.imm_data = 0;
-       wc.qp = &qp->ibqp;
+       wc.qp_num = qp->ibqp.qp_num;
+       wc.qp_context = qp->ibqp.qp_context;
        wc.src_qp = 0;
        wc.wc_flags = 0;
        wc.pkey_index = 0;
diff --git a/drivers/infiniband/hw/ipath/ipath_uc.c 
b/drivers/infiniband/hw/ipath/ipath_uc.c
index 325d663..a03f538 100644
--- a/drivers/infiniband/hw/ipath/ipath_uc.c
+++ b/drivers/infiniband/hw/ipath/ipath_uc.c
@@ -49,7 +49,8 @@ static void complete_last_send(struct ipath_qp *qp, struct 
ipath_swqe *wqe,
                wc->opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
                wc->vendor_err = 0;
                wc->byte_len = wqe->length;
-               wc->qp = &qp->ibqp;
+               wc->qp_num = qp->ibqp.qp_num;
+               wc->qp_context = qp->ibqp.qp_context;
                wc->src_qp = qp->remote_qpn;
                wc->pkey_index = 0;
                wc->slid = qp->remote_ah_attr.dlid;
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c 
b/drivers/infiniband/hw/ipath/ipath_ud.c
index 9a3e546..59fec70 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -66,7 +66,8 @@ bad_lkey:
        wc.vendor_err = 0;
        wc.byte_len = 0;
        wc.imm_data = 0;
-       wc.qp = &qp->ibqp;
+       wc.qp_num = qp->ibqp.qp_num;
+       wc.qp_context = qp->ibqp.qp_context;
        wc.src_qp = 0;
        wc.wc_flags = 0;
        wc.pkey_index = 0;
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c 
b/drivers/infiniband/hw/mthca/mthca_cmd.c
index 7131446..4374c67 100644
--- a/drivers/infiniband/hw/mthca/mthca_cmd.c
+++ b/drivers/infiniband/hw/mthca/mthca_cmd.c
@@ -1858,7 +1858,7 @@ int mthca_MAD_IFC(struct mthca_dev *dev, int ignore_mkey, 
int ignore_bkey,
 
                memset(inbox + 256, 0, 256);
 
-               MTHCA_PUT(inbox, in_wc->qp->qp_num, MAD_IFC_MY_QPN_OFFSET);
+               MTHCA_PUT(inbox, in_wc->qp_num, MAD_IFC_MY_QPN_OFFSET);
                MTHCA_PUT(inbox, in_wc->src_qp,     MAD_IFC_RQPN_OFFSET);
 
                val = in_wc->sl << 4;
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c 
b/drivers/infiniband/hw/mthca/mthca_cq.c
index e3c774b..808850a 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -538,7 +538,8 @@ static inline int mthca_poll_one(struct mthca_dev *dev,
                }
        }
 
-       entry->qp = &(*cur_qp)->ibqp;
+       entry->qp_num = (*cur_qp)->ibqp.qp_num;
+       entry->qp_context = (*cur_qp)->ibqp.qp_context;
 
        if (is_send) {
                wq = &(*cur_qp)->sq;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cq.c 
b/drivers/infiniband/hw/cxgb3/iwch_cq.c
index d7624c1..5a77dcc 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cq.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cq.c
@@ -79,7 +79,8 @@ static int iwch_poll_cq_one(struct iwch_dev *rhp, struct 
iwch_cq *chp,
        ret = 1;
 
        wc->wr_id = cookie;
-       wc->qp = &qhp->ibqp;
+       wc->qp_num = qhp->ibqp.qp_num;
+       wc->qp_context = qhp->ibqp.qp_context;
        wc->vendor_err = CQE_STATUS(cqe);
 
        PDBG("%s qpid 0x%x type %d opcode %d status 0x%x wrid hi 0x%x "

-- 
MST
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to