⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ehca_qp.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				 &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 + -