📄 ehca_qp.c
字号:
&my_qp->pf, update_mask, mqpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(ibqp->device, "hipz_h_modify_qp() failed h_ret=%li " "ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); goto modify_qp_exit2; } if ((my_qp->qp_type == IB_QPT_UD || my_qp->qp_type == IB_QPT_GSI || my_qp->qp_type == IB_QPT_SMI) && statetrans == IB_QPST_SQE2RTS) { /* doorbell to reprocessing wqes */ iosync(); /* serialize GAL register access */ hipz_update_sqa(my_qp, bad_wqe_cnt-1); ehca_gen_dbg("doorbell for %x wqes", bad_wqe_cnt); } if (statetrans == IB_QPST_RESET2INIT || statetrans == IB_QPST_INIT2INIT) { mqpcb->qp_enable = 1; mqpcb->qp_state = EHCA_QPS_INIT; update_mask = 0; update_mask = EHCA_BMASK_SET(MQPCB_MASK_QP_ENABLE, 1); h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, &my_qp->pf, update_mask, mqpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(ibqp->device, "ENABLE in context of " "RESET_2_INIT failed! Maybe you didn't get " "a LID h_ret=%li ehca_qp=%p qp_num=%x", h_ret, my_qp, ibqp->qp_num); goto modify_qp_exit2; } } if (statetrans == IB_QPST_ANY2RESET) { ipz_qeit_reset(&my_qp->ipz_rqueue); ipz_qeit_reset(&my_qp->ipz_squeue); } if (attr_mask & IB_QP_QKEY) my_qp->qkey = attr->qkey;modify_qp_exit2: if (squeue_locked) { /* this means: sqe -> rts */ spin_unlock_irqrestore(&my_qp->spinlock_s, flags); my_qp->sqerr_purgeflag = 1; }modify_qp_exit1: ehca_free_fw_ctrlblock(mqpcb); return ret;}int ehca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata){ struct ehca_qp *my_qp = container_of(ibqp, struct ehca_qp, ib_qp); struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, ib_pd); u32 cur_pid = current->tgid; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && my_pd->ownpid != cur_pid) { ehca_err(ibqp->pd->device, "Invalid caller pid=%x ownpid=%x", cur_pid, my_pd->ownpid); return -EINVAL; } return internal_modify_qp(ibqp, attr, attr_mask, 0);}int ehca_query_qp(struct ib_qp *qp, struct ib_qp_attr *qp_attr, int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr){ struct ehca_qp *my_qp = container_of(qp, struct ehca_qp, ib_qp); struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, ib_pd); struct ehca_shca *shca = container_of(qp->device, struct ehca_shca, ib_device); struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle; struct hcp_modify_qp_control_block *qpcb; u32 cur_pid = current->tgid; int cnt, ret = 0; u64 h_ret; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && my_pd->ownpid != cur_pid) { ehca_err(qp->device, "Invalid caller pid=%x ownpid=%x", cur_pid, my_pd->ownpid); return -EINVAL; } if (qp_attr_mask & QP_ATTR_QUERY_NOT_SUPPORTED) { ehca_err(qp->device, "Invalid attribute mask " "ehca_qp=%p qp_num=%x qp_attr_mask=%x ", my_qp, qp->qp_num, qp_attr_mask); return -EINVAL; } qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!qpcb) { ehca_err(qp->device, "Out of memory for qpcb " "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); return -ENOMEM; } h_ret = hipz_h_query_qp(adapter_handle, my_qp->ipz_qp_handle, &my_qp->pf, qpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(qp->device, "hipz_h_query_qp() failed " "ehca_qp=%p qp_num=%x h_ret=%li", my_qp, qp->qp_num, h_ret); goto query_qp_exit1; } qp_attr->cur_qp_state = ehca2ib_qp_state(qpcb->qp_state); qp_attr->qp_state = qp_attr->cur_qp_state; if (qp_attr->cur_qp_state == -EINVAL) { ret = -EINVAL; ehca_err(qp->device, "Got invalid ehca_qp_state=%x " "ehca_qp=%p qp_num=%x", qpcb->qp_state, my_qp, qp->qp_num); goto query_qp_exit1; } if (qp_attr->qp_state == IB_QPS_SQD) qp_attr->sq_draining = 1; qp_attr->qkey = qpcb->qkey; qp_attr->path_mtu = qpcb->path_mtu; qp_attr->path_mig_state = qpcb->path_migration_state - 1; qp_attr->rq_psn = qpcb->receive_psn; qp_attr->sq_psn = qpcb->send_psn; qp_attr->min_rnr_timer = qpcb->min_rnr_nak_timer_field; qp_attr->cap.max_send_wr = qpcb->max_nr_outst_send_wr-1; qp_attr->cap.max_recv_wr = qpcb->max_nr_outst_recv_wr-1; /* UD_AV CIRCUMVENTION */ if (my_qp->qp_type == IB_QPT_UD) { qp_attr->cap.max_send_sge = qpcb->actual_nr_sges_in_sq_wqe - 2; qp_attr->cap.max_recv_sge = qpcb->actual_nr_sges_in_rq_wqe - 2; } else { qp_attr->cap.max_send_sge = qpcb->actual_nr_sges_in_sq_wqe; qp_attr->cap.max_recv_sge = qpcb->actual_nr_sges_in_rq_wqe; } qp_attr->cap.max_inline_data = my_qp->sq_max_inline_data_size; qp_attr->dest_qp_num = qpcb->dest_qp_nr; qp_attr->pkey_index = EHCA_BMASK_GET(MQPCB_PRIM_P_KEY_IDX, qpcb->prim_p_key_idx); qp_attr->port_num = EHCA_BMASK_GET(MQPCB_PRIM_PHYS_PORT, qpcb->prim_phys_port); qp_attr->timeout = qpcb->timeout; qp_attr->retry_cnt = qpcb->retry_count; qp_attr->rnr_retry = qpcb->rnr_retry_count; qp_attr->alt_pkey_index = EHCA_BMASK_GET(MQPCB_PRIM_P_KEY_IDX, qpcb->alt_p_key_idx); qp_attr->alt_port_num = qpcb->alt_phys_port; qp_attr->alt_timeout = qpcb->timeout_al; qp_attr->max_dest_rd_atomic = qpcb->rdma_nr_atomic_resp_res; qp_attr->max_rd_atomic = qpcb->rdma_atomic_outst_dest_qp; /* primary av */ qp_attr->ah_attr.sl = qpcb->service_level; if (qpcb->send_grh_flag) { qp_attr->ah_attr.ah_flags = IB_AH_GRH; } qp_attr->ah_attr.static_rate = qpcb->max_static_rate; qp_attr->ah_attr.dlid = qpcb->dlid; qp_attr->ah_attr.src_path_bits = qpcb->source_path_bits; qp_attr->ah_attr.port_num = qp_attr->port_num; /* primary GRH */ qp_attr->ah_attr.grh.traffic_class = qpcb->traffic_class; qp_attr->ah_attr.grh.hop_limit = qpcb->hop_limit; qp_attr->ah_attr.grh.sgid_index = qpcb->source_gid_idx; qp_attr->ah_attr.grh.flow_label = qpcb->flow_label; for (cnt = 0; cnt < 16; cnt++) qp_attr->ah_attr.grh.dgid.raw[cnt] = qpcb->dest_gid.byte[cnt]; /* alternate AV */ qp_attr->alt_ah_attr.sl = qpcb->service_level_al; if (qpcb->send_grh_flag_al) { qp_attr->alt_ah_attr.ah_flags = IB_AH_GRH; } qp_attr->alt_ah_attr.static_rate = qpcb->max_static_rate_al; qp_attr->alt_ah_attr.dlid = qpcb->dlid_al; qp_attr->alt_ah_attr.src_path_bits = qpcb->source_path_bits_al; /* alternate GRH */ qp_attr->alt_ah_attr.grh.traffic_class = qpcb->traffic_class_al; qp_attr->alt_ah_attr.grh.hop_limit = qpcb->hop_limit_al; qp_attr->alt_ah_attr.grh.sgid_index = qpcb->source_gid_idx_al; qp_attr->alt_ah_attr.grh.flow_label = qpcb->flow_label_al; for (cnt = 0; cnt < 16; cnt++) qp_attr->alt_ah_attr.grh.dgid.raw[cnt] = qpcb->dest_gid_al.byte[cnt]; /* return init attributes given in ehca_create_qp */ if (qp_init_attr) *qp_init_attr = my_qp->init_attr; if (ehca_debug_level) ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num);query_qp_exit1: ehca_free_fw_ctrlblock(qpcb); return ret;}int ehca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, enum ib_srq_attr_mask attr_mask, struct ib_udata *udata){ struct ehca_qp *my_qp = container_of(ibsrq, struct ehca_qp, ib_srq); struct ehca_pd *my_pd = container_of(ibsrq->pd, struct ehca_pd, ib_pd); struct ehca_shca *shca = container_of(ibsrq->pd->device, struct ehca_shca, ib_device); struct hcp_modify_qp_control_block *mqpcb; u64 update_mask; u64 h_ret; int ret = 0; u32 cur_pid = current->tgid; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && my_pd->ownpid != cur_pid) { ehca_err(ibsrq->pd->device, "Invalid caller pid=%x ownpid=%x", cur_pid, my_pd->ownpid); return -EINVAL; } mqpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!mqpcb) { ehca_err(ibsrq->device, "Could not get zeroed page for mqpcb " "ehca_qp=%p qp_num=%x ", my_qp, my_qp->real_qp_num); return -ENOMEM; } update_mask = 0; if (attr_mask & IB_SRQ_LIMIT) { attr_mask &= ~IB_SRQ_LIMIT; update_mask |= EHCA_BMASK_SET(MQPCB_MASK_CURR_SRQ_LIMIT, 1) | EHCA_BMASK_SET(MQPCB_MASK_QP_AFF_ASYN_EV_LOG_REG, 1); mqpcb->curr_srq_limit = EHCA_BMASK_SET(MQPCB_CURR_SRQ_LIMIT, attr->srq_limit); mqpcb->qp_aff_asyn_ev_log_reg = EHCA_BMASK_SET(QPX_AAELOG_RESET_SRQ_LIMIT, 1); } /* by now, all bits in attr_mask should have been cleared */ if (attr_mask) { ehca_err(ibsrq->device, "invalid attribute mask bits set " "attr_mask=%x", attr_mask); ret = -EINVAL; goto modify_srq_exit0; } if (ehca_debug_level) ehca_dmp(mqpcb, 4*70, "qp_num=%x", my_qp->real_qp_num); h_ret = hipz_h_modify_qp(shca->ipz_hca_handle, my_qp->ipz_qp_handle, NULL, update_mask, mqpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(ibsrq->device, "hipz_h_modify_qp() failed h_ret=%li " "ehca_qp=%p qp_num=%x", h_ret, my_qp, my_qp->real_qp_num); }modify_srq_exit0: ehca_free_fw_ctrlblock(mqpcb); return ret;}int ehca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr){ struct ehca_qp *my_qp = container_of(srq, struct ehca_qp, ib_srq); struct ehca_pd *my_pd = container_of(srq->pd, struct ehca_pd, ib_pd); struct ehca_shca *shca = container_of(srq->device, struct ehca_shca, ib_device); struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle; struct hcp_modify_qp_control_block *qpcb; u32 cur_pid = current->tgid; int ret = 0; u64 h_ret; if (my_pd->ib_pd.uobject && my_pd->ib_pd.uobject->context && my_pd->ownpid != cur_pid) { ehca_err(srq->device, "Invalid caller pid=%x ownpid=%x", cur_pid, my_pd->ownpid); return -EINVAL; } qpcb = ehca_alloc_fw_ctrlblock(GFP_KERNEL); if (!qpcb) { ehca_err(srq->device, "Out of memory for qpcb " "ehca_qp=%p qp_num=%x", my_qp, my_qp->real_qp_num); return -ENOMEM; } h_ret = hipz_h_query_qp(adapter_handle, my_qp->ipz_qp_handle, NULL, qpcb, my_qp->galpas.kernel); if (h_ret != H_SUCCESS) { ret = ehca2ib_return_code(h_ret); ehca_err(srq->device, "hipz_h_query_qp() failed " "ehca_qp=%p qp_num=%x h_ret=%li", my_qp, my_qp->real_qp_num, h_ret); goto query_srq_exit1; } srq_attr->max_wr = qpcb->max_nr_outst_recv_wr - 1; srq_attr->max_sge = 3; srq_attr->srq_limit = EHCA_BMASK_GET( MQPCB_CURR_SRQ_LIMIT, qpcb->curr_srq_limit); if (ehca_debug_level) ehca_dmp(qpcb, 4*70, "qp_num=%x", my_qp->real_qp_num);query_srq_exit1: ehca_free_fw_ctrlblock(qpcb); return ret;}static int internal_destroy_qp(struct ib_device *dev, struct ehca_qp *my_qp, struct ib_uobject *uobject){ struct ehca_shca *shca = container_of(dev, struct ehca_shca, ib_device); struct ehca_pd *my_pd = container_of(my_qp->ib_qp.pd, struct ehca_pd, ib_pd); u32 cur_pid = current->tgid; u32 qp_num = my_qp->real_qp_num; int ret; u64 h_ret; u8 port_num; enum ib_qp_type qp_type; unsigned long flags; if (uobject) { if (my_qp->mm_count_galpa || my_qp->mm_count_rqueue || my_qp->mm_count_squeue) { ehca_err(dev, "Resources still referenced in " "user space qp_num=%x", qp_num); return -EINVAL; } if (my_pd->ownpid != cur_pid) { ehca_err(dev, "Invalid caller pid=%x ownpid=%x", cur_pid, my_pd->ownpid); return -EINVAL; } } if (my_qp->send_cq) { ret = ehca_cq_unassign_qp(my_qp->send_cq, qp_num); if (ret) { ehca_err(dev, "Couldn't unassign qp from " "send_cq ret=%i qp_num=%x cq_num=%x", ret, qp_num, my_qp->send_cq->cq_number); return ret; } } write_lock_irqsave(&ehca_qp_idr_lock, flags); idr_remove(&ehca_qp_idr, my_qp->token); write_unlock_irqrestore(&ehca_qp_idr_lock, flags); h_ret = hipz_h_destroy_qp(shca->ipz_hca_handle, my_qp); if (h_ret != H_SUCCESS) { ehca_err(dev, "hipz_h_destroy_qp() failed h_ret=%li " "ehca_qp=%p qp_num=%x", h_ret, my_qp, qp_num); return ehca2ib_return_code(h_ret); } port_num = my_qp->init_attr.port_num; qp_type = my_qp->init_attr.qp_type; /* no support for IB_QPT_SMI yet */ if (qp_type == IB_QPT_GSI) { struct ib_event event; ehca_info(dev, "device %s: port %x is inactive.", shca->ib_device.name, port_num); event.device = &shca->ib_device; event.event = IB_EVENT_PORT_ERR; event.element.port_num = port_num; shca->sport[port_num - 1].port_state = IB_PORT_DOWN; ib_dispatch_event(&event); } if (HAS_RQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_rqueue); if (HAS_SQ(my_qp)) ipz_queue_dtor(my_pd, &my_qp->ipz_squeue); kmem_cache_free(qp_cache, my_qp); return 0;}int ehca_destroy_qp(struct ib_qp *qp){ return internal_destroy_qp(qp->device, container_of(qp, struct ehca_qp, ib_qp), qp->uobject);}int ehca_destroy_srq(struct ib_srq *srq){ return internal_destroy_qp(srq->device, container_of(srq, struct ehca_qp, ib_srq), srq->uobject);}int ehca_init_qp_cache(void){ qp_cache = kmem_cache_create("ehca_cache_qp", sizeof(struct ehca_qp), 0, SLAB_HWCACHE_ALIGN, NULL); if (!qp_cache) return -ENOMEM; return 0;}void ehca_cleanup_qp_cache(void){ if (qp_cache) kmem_cache_destroy(qp_cache);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -