in prov/psm2/src/psmx2_domain.c [298:497]
int psmx2_domain_open(struct fid_fabric *fabric, struct fi_info *info,
struct fid_domain **domain, void *context)
{
struct psmx2_fid_fabric *fabric_priv;
struct psmx2_fid_domain *domain_priv;
struct psmx2_ep_name *src_addr = info->src_addr;
int mr_mode = (info->domain_attr->mr_mode & FI_MR_BASIC) ? FI_MR_BASIC : 0;
int err, tmp;
FI_INFO(&psmx2_prov, FI_LOG_DOMAIN, "\n");
fabric_priv = container_of(fabric, struct psmx2_fid_fabric,
util_fabric.fabric_fid);
if (!info->domain_attr->name ||
strncmp(info->domain_attr->name, PSMX2_DOMAIN_NAME, strlen(PSMX2_DOMAIN_NAME))) {
err = -FI_EINVAL;
goto err_out;
}
domain_priv = (struct psmx2_fid_domain *) calloc(1, sizeof *domain_priv);
if (!domain_priv) {
err = -FI_ENOMEM;
goto err_out;
}
err = ofi_domain_init(fabric, info, &domain_priv->util_domain, context);
if (err)
goto err_out_free_domain;
/* fclass & context are set in ofi_domain_init */
domain_priv->util_domain.domain_fid.fid.ops = &psmx2_fi_ops;
domain_priv->util_domain.domain_fid.ops = &psmx2_domain_ops;
domain_priv->util_domain.domain_fid.mr = &psmx2_mr_ops;
domain_priv->mr_mode = mr_mode;
domain_priv->mode = info->mode;
domain_priv->caps = info->caps;
domain_priv->fabric = fabric_priv;
domain_priv->progress_thread_enabled =
(info->domain_attr->data_progress == FI_PROGRESS_AUTO);
domain_priv->addr_format = info->addr_format;
if (info->addr_format == FI_ADDR_STR)
src_addr = psmx2_string_to_ep_name(info->src_addr);
/* Use generic lock/unlock functions by default */
domain_priv->av_lock_fn = psmx2_lock;
domain_priv->am_req_pool_lock_fn = psmx2_lock;
domain_priv->trx_ctxt_lock_fn = psmx2_lock;
domain_priv->rma_queue_lock_fn = psmx2_lock;
domain_priv->trigger_queue_lock_fn = psmx2_lock;
domain_priv->peer_lock_fn = psmx2_lock;
domain_priv->sep_lock_fn = psmx2_lock;
domain_priv->trigger_lock_fn = psmx2_lock;
domain_priv->cq_lock_fn = psmx2_lock;
domain_priv->mr_lock_fn = psmx2_lock;
domain_priv->context_lock_fn = psmx2_lock;
domain_priv->poll_trylock_fn = psmx2_trylock;
domain_priv->av_unlock_fn = psmx2_unlock;
domain_priv->am_req_pool_unlock_fn = psmx2_unlock;
domain_priv->trx_ctxt_unlock_fn = psmx2_unlock;
domain_priv->rma_queue_unlock_fn = psmx2_unlock;
domain_priv->trigger_queue_unlock_fn = psmx2_unlock;
domain_priv->peer_unlock_fn = psmx2_unlock;
domain_priv->sep_unlock_fn = psmx2_unlock;
domain_priv->trigger_unlock_fn = psmx2_unlock;
domain_priv->cq_unlock_fn = psmx2_unlock;
domain_priv->mr_unlock_fn = psmx2_unlock;
domain_priv->context_unlock_fn = psmx2_unlock;
domain_priv->poll_unlock_fn = psmx2_unlock;
/* If lock_level env is unset, then set locks based off threading model*/
err = fi_param_get_bool(&psmx2_prov, "lock_level", &tmp);
if (err < 0) {
switch (info->domain_attr->threading) {
case FI_THREAD_DOMAIN:
/* Disable locks not required when serializing access to a domain */
domain_priv->av_lock_fn = psmx2_lock_disabled;
domain_priv->trx_ctxt_lock_fn = psmx2_lock_disabled;
domain_priv->trigger_queue_lock_fn = psmx2_lock_disabled;
domain_priv->sep_lock_fn = psmx2_lock_disabled;
domain_priv->trigger_lock_fn = psmx2_lock_disabled;
domain_priv->cq_lock_fn = psmx2_lock_disabled;
domain_priv->mr_lock_fn = psmx2_lock_disabled;
domain_priv->context_lock_fn = psmx2_lock_disabled;
domain_priv->poll_trylock_fn = psmx2_trylock_disabled;
domain_priv->av_unlock_fn = psmx2_lock_disabled;
domain_priv->trx_ctxt_unlock_fn = psmx2_lock_disabled;
domain_priv->trigger_queue_unlock_fn = psmx2_lock_disabled;
domain_priv->sep_unlock_fn = psmx2_lock_disabled;
domain_priv->trigger_unlock_fn = psmx2_lock_disabled;
domain_priv->cq_unlock_fn = psmx2_lock_disabled;
domain_priv->mr_unlock_fn = psmx2_lock_disabled;
domain_priv->context_unlock_fn = psmx2_lock_disabled;
domain_priv->poll_unlock_fn = psmx2_lock_disabled;
/* Enable lock accessed by the disconnection thread */
domain_priv->peer_lock_fn = psmx2_lock_enabled;
domain_priv->peer_unlock_fn = psmx2_unlock_enabled;
/*
* If FI_RMA or FI_ATOMIC caps are enabled, then locks are
* required for the CQ, am_req_pool, & rma_queue
* due to the PSM2 Recv thread.
* NOTE: am_req_pool & rma_queue are only used when FI_RMA
* and FI_ATOMIC capabilities are enabled.
*/
if ((info->caps & FI_RMA) || (info->caps & FI_ATOMIC)) {
domain_priv->cq_lock_fn = psmx2_lock_enabled;
domain_priv->am_req_pool_lock_fn = psmx2_lock_enabled;
domain_priv->rma_queue_lock_fn = psmx2_lock_enabled;
domain_priv->cq_unlock_fn = psmx2_unlock_enabled;
domain_priv->am_req_pool_unlock_fn = psmx2_unlock_enabled;
domain_priv->rma_queue_unlock_fn = psmx2_unlock_enabled;
}
/*
* Locks accessed by the progress thread are required because
* they are outside the scope of domain access serialization
* implied by FI_THREAD_DOMAIN.
*/
if (domain_priv->progress_thread_enabled) {
domain_priv->trx_ctxt_lock_fn = psmx2_lock_enabled;
domain_priv->poll_trylock_fn = psmx2_trylock_enabled;
domain_priv->cq_lock_fn = psmx2_lock_enabled;
domain_priv->trx_ctxt_unlock_fn = psmx2_unlock_enabled;
domain_priv->poll_unlock_fn = psmx2_unlock_enabled;
domain_priv->cq_unlock_fn = psmx2_unlock_enabled;
if (info->caps & FI_TRIGGER) {
domain_priv->trigger_queue_lock_fn = psmx2_lock_enabled;
domain_priv->trigger_lock_fn = psmx2_lock_enabled;
domain_priv->av_lock_fn = psmx2_lock_enabled;
domain_priv->mr_lock_fn = psmx2_lock_enabled;
domain_priv->context_lock_fn = psmx2_lock_enabled;
domain_priv->trigger_queue_unlock_fn = psmx2_unlock_enabled;
domain_priv->trigger_unlock_fn = psmx2_unlock_enabled;
domain_priv->av_unlock_fn = psmx2_unlock_enabled;
domain_priv->mr_unlock_fn = psmx2_unlock_enabled;
domain_priv->context_unlock_fn = psmx2_unlock_enabled;
}
}
break;
default:
/* Otherwise, enable all locks */
domain_priv->av_lock_fn = psmx2_lock_enabled;
domain_priv->am_req_pool_lock_fn = psmx2_lock_enabled;
domain_priv->trx_ctxt_lock_fn = psmx2_lock_enabled;
domain_priv->rma_queue_lock_fn = psmx2_lock_enabled;
domain_priv->trigger_queue_lock_fn = psmx2_lock_enabled;
domain_priv->peer_lock_fn = psmx2_lock_enabled;
domain_priv->sep_lock_fn = psmx2_lock_enabled;
domain_priv->trigger_lock_fn = psmx2_lock_enabled;
domain_priv->cq_lock_fn = psmx2_lock_enabled;
domain_priv->mr_lock_fn = psmx2_lock_enabled;
domain_priv->context_lock_fn = psmx2_lock_enabled;
domain_priv->poll_trylock_fn = psmx2_trylock_enabled;
domain_priv->av_unlock_fn = psmx2_unlock_enabled;
domain_priv->am_req_pool_unlock_fn = psmx2_unlock_enabled;
domain_priv->trx_ctxt_unlock_fn = psmx2_unlock_enabled;
domain_priv->rma_queue_unlock_fn = psmx2_unlock_enabled;
domain_priv->trigger_queue_unlock_fn = psmx2_unlock_enabled;
domain_priv->peer_unlock_fn = psmx2_unlock_enabled;
domain_priv->sep_unlock_fn = psmx2_unlock_enabled;
domain_priv->trigger_unlock_fn = psmx2_unlock_enabled;
domain_priv->cq_unlock_fn = psmx2_unlock_enabled;
domain_priv->mr_unlock_fn = psmx2_unlock_enabled;
domain_priv->context_unlock_fn = psmx2_unlock_enabled;
domain_priv->poll_unlock_fn = psmx2_unlock_enabled;
break;
}
}
err = psmx2_domain_init(domain_priv, src_addr);
if (info->addr_format == FI_ADDR_STR)
free(src_addr);
if (err)
goto err_out_close_domain;
psmx2_fabric_acquire(fabric_priv);
psmx2_lock(&fabric_priv->domain_lock, 1);
dlist_insert_before(&domain_priv->entry, &fabric_priv->domain_list);
psmx2_unlock(&fabric_priv->domain_lock, 1);
psmx2_init_tag_layout(info);
*domain = &domain_priv->util_domain.domain_fid;
return 0;
err_out_close_domain:
ofi_domain_close(&domain_priv->util_domain);
err_out_free_domain:
free(domain_priv);
err_out:
return err;
}