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

📄 ehca_mrmw.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	pginfo.num_kpages = list_len;	pginfo.hwpage_size = e_fmr->hwpage_size;	pginfo.num_hwpages =		list_len * e_fmr->fmr_page_size / pginfo.hwpage_size;	pginfo.u.fmr.page_list = page_list;	pginfo.next_hwpage =		(iova & (e_fmr->fmr_page_size-1)) / pginfo.hwpage_size;	pginfo.u.fmr.fmr_pgsize = e_fmr->fmr_page_size;	ret = ehca_rereg_mr(shca, e_fmr, (u64 *)iova,			    list_len * e_fmr->fmr_page_size,			    e_fmr->acl, e_pd, &pginfo, &tmp_lkey, &tmp_rkey);	if (ret)		goto map_phys_fmr_exit0;	/* successful reregistration */	e_fmr->fmr_map_cnt++;	e_fmr->ib.ib_fmr.lkey = tmp_lkey;	e_fmr->ib.ib_fmr.rkey = tmp_rkey;	return 0;map_phys_fmr_exit0:	if (ret)		ehca_err(fmr->device, "ret=%i fmr=%p page_list=%p list_len=%x "			 "iova=%lx", ret, fmr, page_list, list_len, iova);	return ret;} /* end ehca_map_phys_fmr() *//*----------------------------------------------------------------------*/int ehca_unmap_fmr(struct list_head *fmr_list){	int ret = 0;	struct ib_fmr *ib_fmr;	struct ehca_shca *shca = NULL;	struct ehca_shca *prev_shca;	struct ehca_mr *e_fmr;	u32 num_fmr = 0;	u32 unmap_fmr_cnt = 0;	/* check all FMR belong to same SHCA, and check internal flag */	list_for_each_entry(ib_fmr, fmr_list, list) {		prev_shca = shca;		if (!ib_fmr) {			ehca_gen_err("bad fmr=%p in list", ib_fmr);			ret = -EINVAL;			goto unmap_fmr_exit0;		}		shca = container_of(ib_fmr->device, struct ehca_shca,				    ib_device);		e_fmr = container_of(ib_fmr, struct ehca_mr, ib.ib_fmr);		if ((shca != prev_shca) && prev_shca) {			ehca_err(&shca->ib_device, "SHCA mismatch, shca=%p "				 "prev_shca=%p e_fmr=%p",				 shca, prev_shca, e_fmr);			ret = -EINVAL;			goto unmap_fmr_exit0;		}		if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {			ehca_err(&shca->ib_device, "not a FMR, e_fmr=%p "				 "e_fmr->flags=%x", e_fmr, e_fmr->flags);			ret = -EINVAL;			goto unmap_fmr_exit0;		}		num_fmr++;	}	/* loop over all FMRs to unmap */	list_for_each_entry(ib_fmr, fmr_list, list) {		unmap_fmr_cnt++;		e_fmr = container_of(ib_fmr, struct ehca_mr, ib.ib_fmr);		shca = container_of(ib_fmr->device, struct ehca_shca,				    ib_device);		ret = ehca_unmap_one_fmr(shca, e_fmr);		if (ret) {			/* unmap failed, stop unmapping of rest of FMRs */			ehca_err(&shca->ib_device, "unmap of one FMR failed, "				 "stop rest, e_fmr=%p num_fmr=%x "				 "unmap_fmr_cnt=%x lkey=%x", e_fmr, num_fmr,				 unmap_fmr_cnt, e_fmr->ib.ib_fmr.lkey);			goto unmap_fmr_exit0;		}	}unmap_fmr_exit0:	if (ret)		ehca_gen_err("ret=%i fmr_list=%p num_fmr=%x unmap_fmr_cnt=%x",			     ret, fmr_list, num_fmr, unmap_fmr_cnt);	return ret;} /* end ehca_unmap_fmr() *//*----------------------------------------------------------------------*/int ehca_dealloc_fmr(struct ib_fmr *fmr){	int ret;	u64 h_ret;	struct ehca_shca *shca =		container_of(fmr->device, struct ehca_shca, ib_device);	struct ehca_mr *e_fmr = container_of(fmr, struct ehca_mr, ib.ib_fmr);	if (!(e_fmr->flags & EHCA_MR_FLAG_FMR)) {		ehca_err(fmr->device, "not a FMR, e_fmr=%p e_fmr->flags=%x",			 e_fmr, e_fmr->flags);		ret = -EINVAL;		goto free_fmr_exit0;	}	h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_fmr);	if (h_ret != H_SUCCESS) {		ehca_err(fmr->device, "hipz_free_mr failed, h_ret=%li e_fmr=%p "			 "hca_hndl=%lx fmr_hndl=%lx fmr->lkey=%x",			 h_ret, e_fmr, shca->ipz_hca_handle.handle,			 e_fmr->ipz_mr_handle.handle, fmr->lkey);		ret = ehca2ib_return_code(h_ret);		goto free_fmr_exit0;	}	/* successful deregistration */	ehca_mr_delete(e_fmr);	return 0;free_fmr_exit0:	if (ret)		ehca_err(&shca->ib_device, "ret=%i fmr=%p", ret, fmr);	return ret;} /* end ehca_dealloc_fmr() *//*----------------------------------------------------------------------*/int ehca_reg_mr(struct ehca_shca *shca,		struct ehca_mr *e_mr,		u64 *iova_start,		u64 size,		int acl,		struct ehca_pd *e_pd,		struct ehca_mr_pginfo *pginfo,		u32 *lkey, /*OUT*/		u32 *rkey) /*OUT*/{	int ret;	u64 h_ret;	u32 hipz_acl;	struct ehca_mr_hipzout_parms hipzout;	ehca_mrmw_map_acl(acl, &hipz_acl);	ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl);	if (ehca_use_hp_mr == 1)		hipz_acl |= 0x00000001;	h_ret = hipz_h_alloc_resource_mr(shca->ipz_hca_handle, e_mr,					 (u64)iova_start, size, hipz_acl,					 e_pd->fw_pd, &hipzout);	if (h_ret != H_SUCCESS) {		ehca_err(&shca->ib_device, "hipz_alloc_mr failed, h_ret=%li "			 "hca_hndl=%lx", h_ret, shca->ipz_hca_handle.handle);		ret = ehca2ib_return_code(h_ret);		goto ehca_reg_mr_exit0;	}	e_mr->ipz_mr_handle = hipzout.handle;	ret = ehca_reg_mr_rpages(shca, e_mr, pginfo);	if (ret)		goto ehca_reg_mr_exit1;	/* successful registration */	e_mr->num_kpages = pginfo->num_kpages;	e_mr->num_hwpages = pginfo->num_hwpages;	e_mr->hwpage_size = pginfo->hwpage_size;	e_mr->start = iova_start;	e_mr->size = size;	e_mr->acl = acl;	*lkey = hipzout.lkey;	*rkey = hipzout.rkey;	return 0;ehca_reg_mr_exit1:	h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);	if (h_ret != H_SUCCESS) {		ehca_err(&shca->ib_device, "h_ret=%li shca=%p e_mr=%p "			 "iova_start=%p size=%lx acl=%x e_pd=%p lkey=%x "			 "pginfo=%p num_kpages=%lx num_hwpages=%lx ret=%i",			 h_ret, shca, e_mr, iova_start, size, acl, e_pd,			 hipzout.lkey, pginfo, pginfo->num_kpages,			 pginfo->num_hwpages, ret);		ehca_err(&shca->ib_device, "internal error in ehca_reg_mr, "			 "not recoverable");	}ehca_reg_mr_exit0:	if (ret)		ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p "			 "iova_start=%p size=%lx acl=%x e_pd=%p pginfo=%p "			 "num_kpages=%lx num_hwpages=%lx",			 ret, shca, e_mr, iova_start, size, acl, e_pd, pginfo,			 pginfo->num_kpages, pginfo->num_hwpages);	return ret;} /* end ehca_reg_mr() *//*----------------------------------------------------------------------*/int ehca_reg_mr_rpages(struct ehca_shca *shca,		       struct ehca_mr *e_mr,		       struct ehca_mr_pginfo *pginfo){	int ret = 0;	u64 h_ret;	u32 rnum;	u64 rpage;	u32 i;	u64 *kpage;	if (!pginfo->num_hwpages) /* in case of fmr */		return 0;	kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL);	if (!kpage) {		ehca_err(&shca->ib_device, "kpage alloc failed");		ret = -ENOMEM;		goto ehca_reg_mr_rpages_exit0;	}	/* max MAX_RPAGES ehca mr pages per register call */	for (i = 0; i < NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES); i++) {		if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {			rnum = pginfo->num_hwpages % MAX_RPAGES; /* last shot */			if (rnum == 0)				rnum = MAX_RPAGES;      /* last shot is full */		} else			rnum = MAX_RPAGES;		ret = ehca_set_pagebuf(pginfo, rnum, kpage);		if (ret) {			ehca_err(&shca->ib_device, "ehca_set_pagebuf "				 "bad rc, ret=%i rnum=%x kpage=%p",				 ret, rnum, kpage);			goto ehca_reg_mr_rpages_exit1;		}		if (rnum > 1) {			rpage = virt_to_abs(kpage);			if (!rpage) {				ehca_err(&shca->ib_device, "kpage=%p i=%x",					 kpage, i);				ret = -EFAULT;				goto ehca_reg_mr_rpages_exit1;			}		} else			rpage = *kpage;		h_ret = hipz_h_register_rpage_mr(			shca->ipz_hca_handle, e_mr,			ehca_encode_hwpage_size(pginfo->hwpage_size),			0, rpage, rnum);		if (i == NUM_CHUNKS(pginfo->num_hwpages, MAX_RPAGES) - 1) {			/*			 * check for 'registration complete'==H_SUCCESS			 * and for 'page registered'==H_PAGE_REGISTERED			 */			if (h_ret != H_SUCCESS) {				ehca_err(&shca->ib_device, "last "					 "hipz_reg_rpage_mr failed, h_ret=%li "					 "e_mr=%p i=%x hca_hndl=%lx mr_hndl=%lx"					 " lkey=%x", h_ret, e_mr, i,					 shca->ipz_hca_handle.handle,					 e_mr->ipz_mr_handle.handle,					 e_mr->ib.ib_mr.lkey);				ret = ehca2ib_return_code(h_ret);				break;			} else				ret = 0;		} else if (h_ret != H_PAGE_REGISTERED) {			ehca_err(&shca->ib_device, "hipz_reg_rpage_mr failed, "				 "h_ret=%li e_mr=%p i=%x lkey=%x hca_hndl=%lx "				 "mr_hndl=%lx", h_ret, e_mr, i,				 e_mr->ib.ib_mr.lkey,				 shca->ipz_hca_handle.handle,				 e_mr->ipz_mr_handle.handle);			ret = ehca2ib_return_code(h_ret);			break;		} else			ret = 0;	} /* end for(i) */ehca_reg_mr_rpages_exit1:	ehca_free_fw_ctrlblock(kpage);ehca_reg_mr_rpages_exit0:	if (ret)		ehca_err(&shca->ib_device, "ret=%i shca=%p e_mr=%p pginfo=%p "			 "num_kpages=%lx num_hwpages=%lx", ret, shca, e_mr,			 pginfo, pginfo->num_kpages, pginfo->num_hwpages);	return ret;} /* end ehca_reg_mr_rpages() *//*----------------------------------------------------------------------*/inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca,				struct ehca_mr *e_mr,				u64 *iova_start,				u64 size,				u32 acl,				struct ehca_pd *e_pd,				struct ehca_mr_pginfo *pginfo,				u32 *lkey, /*OUT*/				u32 *rkey) /*OUT*/{	int ret;	u64 h_ret;	u32 hipz_acl;	u64 *kpage;	u64 rpage;	struct ehca_mr_pginfo pginfo_save;	struct ehca_mr_hipzout_parms hipzout;	ehca_mrmw_map_acl(acl, &hipz_acl);	ehca_mrmw_set_pgsize_hipz_acl(pginfo->hwpage_size, &hipz_acl);	kpage = ehca_alloc_fw_ctrlblock(GFP_KERNEL);	if (!kpage) {		ehca_err(&shca->ib_device, "kpage alloc failed");		ret = -ENOMEM;		goto ehca_rereg_mr_rereg1_exit0;	}	pginfo_save = *pginfo;	ret = ehca_set_pagebuf(pginfo, pginfo->num_hwpages, kpage);	if (ret) {		ehca_err(&shca->ib_device, "set pagebuf failed, e_mr=%p "			 "pginfo=%p type=%x num_kpages=%lx num_hwpages=%lx "			 "kpage=%p", e_mr, pginfo, pginfo->type,			 pginfo->num_kpages, pginfo->num_hwpages, kpage);		goto ehca_rereg_mr_rereg1_exit1;	}	rpage = virt_to_abs(kpage);	if (!rpage) {		ehca_err(&shca->ib_device, "kpage=%p", kpage);		ret = -EFAULT;		goto ehca_rereg_mr_rereg1_exit1;	}	h_ret = hipz_h_reregister_pmr(shca->ipz_hca_handle, e_mr,				      (u64)iova_start, size, hipz_acl,				      e_pd->fw_pd, rpage, &hipzout);	if (h_ret != H_SUCCESS) {		/*		 * reregistration unsuccessful, try it again with the 3 hCalls,		 * e.g. this is required in case H_MR_CONDITION		 * (MW bound or MR is shared)		 */		ehca_warn(&shca->ib_device, "hipz_h_reregister_pmr failed "			  "(Rereg1), h_ret=%li e_mr=%p", h_ret, e_mr);		*pginfo = pginfo_save;		ret = -EAGAIN;	} else if ((u64 *)hipzout.vaddr != iova_start) {		ehca_err(&shca->ib_device, "PHYP changed iova_start in "			 "rereg_pmr, iova_start=%p iova_start_out=%lx e_mr=%p "			 "mr_handle=%lx lkey=%x lkey_out=%x", iova_start,			 hipzout.vaddr, e_mr, e_mr->ipz_mr_handle.handle,			 e_mr->ib.ib_mr.lkey, hipzout.lkey);		ret = -EFAULT;	} else {		/*		 * successful reregistration		 * note: start and start_out are identical for eServer HCAs		 */		e_mr->num_kpages = pginfo->num_kpages;		e_mr->num_hwpages = pginfo->num_hwpages;		e_mr->hwpage_size = pginfo->hwpage_size;		e_mr->start = iova_start;		e_mr->size = size;		e_mr->acl = acl;		*lkey = hipzout.lkey;		*rkey = hipzout.rkey;	}ehca_rereg_mr_rereg1_exit1:	ehca_free_fw_ctrlblock(kpage);ehca_rereg_mr_rereg1_exit0:	if ( ret && (ret != -EAGAIN) )		ehca_err(&shca->ib_device, "ret=%i lkey=%x rkey=%x "			 "pginfo=%p num_kpages=%lx num_hwpages=%lx",			 ret, *lkey, *rkey, pginfo, pginfo->num_kpages,			 pginfo->num_hwpages);	return ret;} /* end ehca_rereg_mr_rereg1() *//*----------------------------------------------------------------------*/int ehca_rereg_mr(struct ehca_shca *shca,		  struct ehca_mr *e_mr,		  u64 *iova_start,		  u64 size,		  int acl,		  struct ehca_pd *e_pd,		  struct ehca_mr_pginfo *pginfo,		  u32 *lkey,		  u32 *rkey){	int ret = 0;	u64 h_ret;	int rereg_1_hcall = 1; /* 1: use hipz_h_reregister_pmr directly */	int rereg_3_hcall = 0; /* 1: use 3 hipz calls for reregistration */	/* first determine reregistration hCall(s) */	if ((pginfo->num_hwpages > MAX_RPAGES) ||	    (e_mr->num_hwpages > MAX_RPAGES) ||	    (pginfo->num_hwpages > e_mr->num_hwpages)) {		ehca_dbg(&shca->ib_device, "Rereg3 case, "			 "pginfo->num_hwpages=%lx e_mr->num_hwpages=%x",			 pginfo->num_hwpages, e_mr->num_hwpages);		rereg_1_hcall = 0;		rereg_3_hcall = 1;	}	if (e_mr->flags & EHCA_MR_FLAG_MAXMR) {	/* check for max-MR */		rereg_1_hcall = 0;		rereg_3_hcall = 1;		e_mr->flags &= ~EHCA_MR_FLAG_MAXMR;		ehca_err(&shca->ib_device, "Rereg MR for max-MR! e_mr=%p",			 e_mr);	}	if (rereg_1_hcall) {		ret = ehca_rereg_mr_rereg1(shca, e_mr, iova_start, size,					   acl, e_pd, pginfo, lkey, rkey);		if (ret) {			if (ret == -EAGAIN)				rereg_3_hcall = 1;			else				goto ehca_rereg_mr_exit0;		}	}	if (rereg_3_hcall) {		struct ehca_mr save_mr;		/* first deregister old MR */		h_ret = hipz_h_free_resource_mr(shca->ipz_hca_handle, e_mr);		if (h_ret != H_SUCCESS) {			ehca_err(&shca->ib_device, "hipz_free_mr failed, "				 "h_ret=%li e_mr=%p hca_hndl=%lx mr_hndl=%lx "				 "mr->lkey=%x",				 h_ret, e_mr, shca->ipz_hca_handle.handle,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -