static int sock_regattr(struct fid_domain *domain, const struct fi_mr_attr *attr, uint64_t flags, struct fid_mr **mr) { struct fi_eq_entry eq_entry; struct sock_domain *dom; struct sock_mr *_mr; uint64_t key; dom = container_of(domain, struct sock_domain, dom_fid); if (!(dom->info.mode & FI_PROV_MR_ATTR) && ((attr->requested_key > IDX_MAX_INDEX) || idm_lookup(&dom->mr_idm, (int) attr->requested_key))) return -FI_ENOKEY; _mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1)); if (!_mr) return -FI_ENOMEM; _mr->mr_fid.fid.fclass = FI_CLASS_MR; _mr->mr_fid.fid.context = attr->context; _mr->mr_fid.fid.ops = &sock_mr_fi_ops; _mr->domain = dom; _mr->access = attr->access; _mr->flags = flags; _mr->offset = (flags & FI_MR_OFFSET) ? (uintptr_t) attr->mr_iov[0].iov_base + attr->offset : (uintptr_t) attr->mr_iov[0].iov_base; fastlock_acquire(&dom->lock); key = (dom->info.mode & FI_PROV_MR_ATTR) ? sock_get_mr_key(dom) : (uint16_t) attr->requested_key; if (idm_set(&dom->mr_idm, key, _mr) < 0) goto err; _mr->mr_fid.key = key; _mr->mr_fid.mem_desc = (void *)key; fastlock_release(&dom->lock); _mr->iov_count = attr->iov_count; memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count); *mr = &_mr->mr_fid; atomic_inc(&dom->ref); if (dom->mr_eq) { eq_entry.fid = &domain->fid; eq_entry.context = attr->context; return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE, &eq_entry, sizeof(eq_entry), 0); } return 0; err: fastlock_release(&dom->lock); free(_mr); return -errno; }
static int sock_regattr(struct fid *fid, const struct fi_mr_attr *attr, uint64_t flags, struct fid_mr **mr) { struct fi_eq_entry eq_entry; struct sock_domain *dom; struct sock_mr *_mr; uint64_t key; struct fid_domain *domain; RbtStatus res; int ret = 0; if (fid->fclass != FI_CLASS_DOMAIN || !attr || attr->iov_count <= 0) { return -FI_EINVAL; } domain = container_of(fid, struct fid_domain, fid); dom = container_of(domain, struct sock_domain, dom_fid); _mr = calloc(1, sizeof(*_mr) + sizeof(_mr->mr_iov) * (attr->iov_count - 1)); if (!_mr) return -FI_ENOMEM; fastlock_acquire(&dom->lock); if (dom->attr.mr_mode == FI_MR_SCALABLE && sock_mr_get_entry(dom, attr->requested_key) != NULL) { ret = -FI_ENOKEY; goto err; } _mr->mr_fid.fid.fclass = FI_CLASS_MR; _mr->mr_fid.fid.context = attr->context; _mr->mr_fid.fid.ops = &sock_mr_fi_ops; _mr->domain = dom; _mr->access = attr->access; _mr->flags = flags; _mr->offset = (dom->attr.mr_mode == FI_MR_SCALABLE) ? (uintptr_t) attr->mr_iov[0].iov_base + attr->offset : (uintptr_t) attr->mr_iov[0].iov_base; key = (dom->attr.mr_mode == FI_MR_BASIC) ? sock_get_mr_key(dom) : attr->requested_key; _mr->key = key; res = rbtInsert(dom->mr_heap, &_mr->key, _mr); if (res != RBT_STATUS_OK) { ret = -FI_ENOMEM; goto err; } _mr->mr_fid.key = key; _mr->mr_fid.mem_desc = (void *) (uintptr_t) key; fastlock_release(&dom->lock); _mr->iov_count = attr->iov_count; memcpy(&_mr->mr_iov, attr->mr_iov, sizeof(_mr->mr_iov) * attr->iov_count); *mr = &_mr->mr_fid; atomic_inc(&dom->ref); if (dom->mr_eq) { eq_entry.fid = &domain->fid; eq_entry.context = attr->context; return sock_eq_report_event(dom->mr_eq, FI_MR_COMPLETE, &eq_entry, sizeof(eq_entry), 0); } return 0; err: fastlock_release(&dom->lock); free(_mr); return ret; }