From 7690d4c30f8f9650859f8e9c304dcf61e0872d70 Mon Sep 17 00:00:00 2001 From: "David J. Wilder" Date: Fri, 8 Aug 2008 15:51:29 -0700 Subject: [PATCH] --- yaml --- r: 108285 b: refs/heads/master c: b1404069f64457c94de241738fdca142c2e5698f h: refs/heads/master i: 108283: 772abbad3e449940e214727fe3bfc97471cb8900 v: v3 --- [refs] | 2 +- .../drivers/infiniband/hw/ehca/ehca_classes.h | 9 --- trunk/drivers/infiniband/hw/ehca/ehca_qes.h | 1 - trunk/drivers/infiniband/hw/ehca/ehca_qp.c | 48 ++++----------- trunk/drivers/infiniband/hw/ehca/ehca_reqs.c | 60 ++++--------------- trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c | 17 ++++-- 6 files changed, 39 insertions(+), 98 deletions(-) diff --git a/[refs] b/[refs] index dca3e3960e5a..5fe17820ea37 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6773f079b72ab0200fe9afa9bb0c656a6af5400c +refs/heads/master: b1404069f64457c94de241738fdca142c2e5698f diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h index 1ab919f836a8..0b0618edd645 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_classes.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_classes.h @@ -156,14 +156,6 @@ struct ehca_mod_qp_parm { #define EHCA_MOD_QP_PARM_MAX 4 -#define QMAP_IDX_MASK 0xFFFFULL - -/* struct for tracking if cqes have been reported to the application */ -struct ehca_qmap_entry { - u16 app_wr_id; - u16 reported; -}; - struct ehca_qp { union { struct ib_qp ib_qp; @@ -173,7 +165,6 @@ struct ehca_qp { enum ehca_ext_qp_type ext_type; enum ib_qp_state state; struct ipz_queue ipz_squeue; - struct ehca_qmap_entry *sq_map; struct ipz_queue ipz_rqueue; struct h_galpas galpas; u32 qkey; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qes.h b/trunk/drivers/infiniband/hw/ehca/ehca_qes.h index 5d28e3e98a20..818803057ebf 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qes.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qes.h @@ -213,7 +213,6 @@ struct ehca_wqe { #define WC_STATUS_ERROR_BIT 0x80000000 #define WC_STATUS_REMOTE_ERROR_FLAGS 0x0000F800 #define WC_STATUS_PURGE_BIT 0x10 -#define WC_SEND_RECEIVE_BIT 0x80 struct ehca_cqe { u64 work_request_id; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index b6bcee036734..ea13efddf175 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -412,7 +412,6 @@ static struct ehca_qp *internal_create_qp( struct ehca_shca *shca = container_of(pd->device, struct ehca_shca, ib_device); struct ib_ucontext *context = NULL; - u32 nr_qes; u64 h_ret; int is_llqp = 0, has_srq = 0; int qp_type, max_send_sge, max_recv_sge, ret; @@ -716,15 +715,6 @@ static struct ehca_qp *internal_create_qp( "and pages ret=%i", ret); goto create_qp_exit2; } - nr_qes = my_qp->ipz_squeue.queue_length / - my_qp->ipz_squeue.qe_size; - my_qp->sq_map = vmalloc(nr_qes * - sizeof(struct ehca_qmap_entry)); - if (!my_qp->sq_map) { - ehca_err(pd->device, "Couldn't allocate squeue " - "map ret=%i", ret); - goto create_qp_exit3; - } } if (HAS_RQ(my_qp)) { @@ -734,7 +724,7 @@ static struct ehca_qp *internal_create_qp( if (ret) { ehca_err(pd->device, "Couldn't initialize rqueue " "and pages ret=%i", ret); - goto create_qp_exit4; + goto create_qp_exit3; } } @@ -780,7 +770,7 @@ static struct ehca_qp *internal_create_qp( if (!my_qp->mod_qp_parm) { ehca_err(pd->device, "Could not alloc mod_qp_parm"); - goto create_qp_exit5; + goto create_qp_exit4; } } } @@ -790,7 +780,7 @@ static struct ehca_qp *internal_create_qp( h_ret = ehca_define_sqp(shca, my_qp, init_attr); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); - goto create_qp_exit6; + goto create_qp_exit5; } } @@ -799,7 +789,7 @@ static struct ehca_qp *internal_create_qp( if (ret) { ehca_err(pd->device, "Couldn't assign qp to send_cq ret=%i", ret); - goto create_qp_exit6; + goto create_qp_exit5; } } @@ -825,26 +815,22 @@ static struct ehca_qp *internal_create_qp( if (ib_copy_to_udata(udata, &resp, sizeof resp)) { ehca_err(pd->device, "Copy to udata failed"); ret = -EINVAL; - goto create_qp_exit7; + goto create_qp_exit6; } } return my_qp; -create_qp_exit7: +create_qp_exit6: ehca_cq_unassign_qp(my_qp->send_cq, my_qp->real_qp_num); -create_qp_exit6: +create_qp_exit5: kfree(my_qp->mod_qp_parm); -create_qp_exit5: +create_qp_exit4: if (HAS_RQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); -create_qp_exit4: - if (HAS_SQ(my_qp)) - vfree(my_qp->sq_map); - create_qp_exit3: if (HAS_SQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); @@ -1548,6 +1534,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, if (attr_mask & IB_QP_QKEY) my_qp->qkey = attr->qkey; + my_qp->state = qp_new_state; + modify_qp_exit2: if (squeue_locked) { /* this means: sqe -> rts */ spin_unlock_irqrestore(&my_qp->spinlock_s, flags); @@ -1563,8 +1551,6 @@ static int internal_modify_qp(struct ib_qp *ibqp, int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata) { - int ret = 0; - struct ehca_shca *shca = container_of(ibqp->device, struct ehca_shca, ib_device); struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); @@ -1611,18 +1597,12 @@ int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, attr->qp_state, my_qp->init_attr.port_num, ibqp->qp_type); spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); - goto out; + return 0; } spin_unlock_irqrestore(&sport->mod_sqp_lock, flags); } - ret = internal_modify_qp(ibqp, attr, attr_mask, 0); - -out: - if ((ret == 0) && (attr_mask & IB_QP_STATE)) - my_qp->state = attr->qp_state; - - return ret; + return internal_modify_qp(ibqp, attr, attr_mask, 0); } void ehca_recover_sqp(struct ib_qp *sqp) @@ -1993,10 +1973,8 @@ static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, if (HAS_RQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); - if (HAS_SQ(my_qp)) { + if (HAS_SQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); - vfree(my_qp->sq_map); - } kmem_cache_free(qp_cache, my_qp); atomic_dec(&shca->num_qps); return 0; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c index 4426d82fe798..898c8b5c38dd 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -139,7 +139,6 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr) static inline int ehca_write_swqe(struct ehca_qp *qp, struct ehca_wqe *wqe_p, const struct ib_send_wr *send_wr, - u32 sq_map_idx, int hidden) { u32 idx; @@ -158,11 +157,7 @@ static inline int ehca_write_swqe(struct ehca_qp *qp, /* clear wqe header until sglist */ memset(wqe_p, 0, offsetof(struct ehca_wqe, u.ud_av.sg_list)); - wqe_p->work_request_id = send_wr->wr_id & ~QMAP_IDX_MASK; - wqe_p->work_request_id |= sq_map_idx & QMAP_IDX_MASK; - - qp->sq_map[sq_map_idx].app_wr_id = send_wr->wr_id & QMAP_IDX_MASK; - qp->sq_map[sq_map_idx].reported = 0; + wqe_p->work_request_id = send_wr->wr_id; switch (send_wr->opcode) { case IB_WR_SEND: @@ -386,7 +381,6 @@ static inline int post_one_send(struct ehca_qp *my_qp, { struct ehca_wqe *wqe_p; int ret; - u32 sq_map_idx; u64 start_offset = my_qp->ipz_squeue.current_q_offset; /* get pointer next to free WQE */ @@ -399,15 +393,8 @@ static inline int post_one_send(struct ehca_qp *my_qp, "qp_num=%x", my_qp->ib_qp.qp_num); return -ENOMEM; } - - /* - * Get the index of the WQE in the send queue. The same index is used - * for writing into the sq_map. - */ - sq_map_idx = start_offset / my_qp->ipz_squeue.qe_size; - /* write a SEND WQE into the QUEUE */ - ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, sq_map_idx, hidden); + ret = ehca_write_swqe(my_qp, wqe_p, cur_send_wr, hidden); /* * if something failed, * reset the free entry pointer to the start value @@ -602,7 +589,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) struct ehca_qp *my_qp; int cqe_count = 0, is_error; -repoll: +poll_cq_one_read_cqe: cqe = (struct ehca_cqe *) ipz_qeit_get_inc_valid(&my_cq->ipz_queue); if (!cqe) { @@ -630,7 +617,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) ehca_dmp(cqe, 64, "cq_num=%x qp_num=%x", my_cq->cq_number, cqe->local_qp_number); /* ignore this purged cqe */ - goto repoll; + goto poll_cq_one_read_cqe; } spin_lock_irqsave(&qp->spinlock_s, flags); purgeflag = qp->sqerr_purgeflag; @@ -649,7 +636,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) * that caused sqe and turn off purge flag */ qp->sqerr_purgeflag = 0; - goto repoll; + goto poll_cq_one_read_cqe; } } @@ -667,34 +654,8 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) my_cq, my_cq->cq_number); } - read_lock(&ehca_qp_idr_lock); - my_qp = idr_find(&ehca_qp_idr, cqe->qp_token); - read_unlock(&ehca_qp_idr_lock); - if (!my_qp) - goto repoll; - wc->qp = &my_qp->ib_qp; - - if (!(cqe->w_completion_flags & WC_SEND_RECEIVE_BIT)) { - struct ehca_qmap_entry *qmap_entry; - /* - * We got a send completion and need to restore the original - * wr_id. - */ - qmap_entry = &my_qp->sq_map[cqe->work_request_id & - QMAP_IDX_MASK]; - - if (qmap_entry->reported) { - ehca_warn(cq->device, "Double cqe on qp_num=%#x", - my_qp->real_qp_num); - /* found a double cqe, discard it and read next one */ - goto repoll; - } - wc->wr_id = cqe->work_request_id & ~QMAP_IDX_MASK; - wc->wr_id |= qmap_entry->app_wr_id; - qmap_entry->reported = 1; - } else - /* We got a receive completion. */ - wc->wr_id = cqe->work_request_id; + /* we got a completion! */ + wc->wr_id = cqe->work_request_id; /* eval ib_wc_opcode */ wc->opcode = ib_wc_opcode[cqe->optype]-1; @@ -706,7 +667,7 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) ehca_dmp(cqe, 64, "ehca_cq=%p cq_num=%x", my_cq, my_cq->cq_number); /* update also queue adder to throw away this entry!!! */ - goto repoll; + goto poll_cq_one_exit0; } /* eval ib_wc_status */ @@ -717,6 +678,11 @@ static inline int ehca_poll_cq_one(struct ib_cq *cq, struct ib_wc *wc) } else wc->status = IB_WC_SUCCESS; + read_lock(&ehca_qp_idr_lock); + my_qp = idr_find(&ehca_qp_idr, cqe->qp_token); + wc->qp = &my_qp->ib_qp; + read_unlock(&ehca_qp_idr_lock); + wc->byte_len = cqe->nr_bytes_transferred; wc->pkey_index = cqe->pkey_index; wc->slid = cqe->rlid; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 7ebc400a4b3d..341ffedafed6 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -202,7 +202,7 @@ static void ipoib_cm_free_rx_ring(struct net_device *dev, dev_kfree_skb_any(rx_ring[i].skb); } - kfree(rx_ring); + vfree(rx_ring); } static void ipoib_cm_start_rx_drain(struct ipoib_dev_priv *priv) @@ -352,9 +352,14 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i int ret; int i; - rx->rx_ring = kcalloc(ipoib_recvq_size, sizeof *rx->rx_ring, GFP_KERNEL); - if (!rx->rx_ring) + rx->rx_ring = vmalloc(ipoib_recvq_size * sizeof *rx->rx_ring); + if (!rx->rx_ring) { + printk(KERN_WARNING "%s: failed to allocate CM non-SRQ ring (%d entries)\n", + priv->ca->name, ipoib_recvq_size); return -ENOMEM; + } + + memset(rx->rx_ring, 0, ipoib_recvq_size * sizeof *rx->rx_ring); t = kmalloc(sizeof *t, GFP_KERNEL); if (!t) { @@ -1494,14 +1499,16 @@ static void ipoib_cm_create_srq(struct net_device *dev, int max_sge) return; } - priv->cm.srq_ring = kzalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring, - GFP_KERNEL); + priv->cm.srq_ring = vmalloc(ipoib_recvq_size * sizeof *priv->cm.srq_ring); if (!priv->cm.srq_ring) { printk(KERN_WARNING "%s: failed to allocate CM SRQ ring (%d entries)\n", priv->ca->name, ipoib_recvq_size); ib_destroy_srq(priv->cm.srq); priv->cm.srq = NULL; + return; } + + memset(priv->cm.srq_ring, 0, ipoib_recvq_size * sizeof *priv->cm.srq_ring); } int ipoib_cm_dev_init(struct net_device *dev)