in prov/bgq/src/fi_bgq_cq.c [416:596]
int fi_bgq_cq_open(struct fid_domain *dom,
struct fi_cq_attr *attr,
struct fid_cq **cq, void *context)
{
int ret;
struct fi_bgq_cq *bgq_cq;
int lock_required;
if (!attr) {
FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_CQ,
"no attr supplied\n");
errno = FI_EINVAL;
return -errno;
}
ret = fi_bgq_fid_check(&dom->fid, FI_CLASS_DOMAIN, "domain");
if (ret)
return ret;
bgq_cq = calloc(1, sizeof(*bgq_cq));
if (!bgq_cq) {
errno = FI_ENOMEM;
goto err;
}
bgq_cq->cq_fid.fid.fclass = FI_CLASS_CQ;
bgq_cq->cq_fid.fid.context= context;
bgq_cq->cq_fid.fid.ops = &fi_bgq_fi_ops;
bgq_cq->size = attr->size ? attr->size : FI_BGQ_DEFAULT_CQ_DEPTH;
bgq_cq->domain = (struct fi_bgq_domain *) dom;
bgq_cq->format = attr->format ? attr->format : FI_CQ_FORMAT_CONTEXT;
bgq_cq->pending_head = NULL;
bgq_cq->pending_tail = NULL;
bgq_cq->completed_head = NULL;
bgq_cq->completed_tail = NULL;
bgq_cq->err_head = NULL;
bgq_cq->err_tail = NULL;
switch (bgq_cq->domain->threading) {
case FI_THREAD_ENDPOINT:
case FI_THREAD_DOMAIN:
case FI_THREAD_COMPLETION:
lock_required = 0;
break;
case FI_THREAD_FID:
case FI_THREAD_UNSPEC:
case FI_THREAD_SAFE:
lock_required = 1;
break;
default:
errno = FI_EINVAL;
goto err;
}
if (lock_required == 0 &&
bgq_cq->format == FI_CQ_FORMAT_UNSPEC) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_UNSPEC, 0);
} else if (lock_required == 0 &&
bgq_cq->format == FI_CQ_FORMAT_CONTEXT) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_CONTEXT, 0);
} else if (lock_required == 0 &&
bgq_cq->format == FI_CQ_FORMAT_MSG) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_MSG, 0);
} else if (lock_required == 0 &&
bgq_cq->format == FI_CQ_FORMAT_DATA) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_DATA, 0);
} else if (lock_required == 0 &&
bgq_cq->format == FI_CQ_FORMAT_TAGGED) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_TAGGED, 0);
} else if (lock_required == 1 &&
bgq_cq->format == FI_CQ_FORMAT_UNSPEC) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_UNSPEC, 1);
} else if (lock_required == 1 &&
bgq_cq->format == FI_CQ_FORMAT_CONTEXT) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_CONTEXT, 1);
} else if (lock_required == 1 &&
bgq_cq->format == FI_CQ_FORMAT_MSG) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_MSG, 1);
} else if (lock_required == 1 &&
bgq_cq->format == FI_CQ_FORMAT_DATA) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_DATA, 1);
} else if (lock_required == 1 &&
bgq_cq->format == FI_CQ_FORMAT_TAGGED) {
bgq_cq->cq_fid.ops =
&FI_BGQ_CQ_OPS_STRUCT_NAME(FI_CQ_FORMAT_TAGGED, 1);
} else {
bgq_cq->cq_fid.ops =
&fi_bgq_ops_cq_default;
}
/* initialize the 'local completion' direct-put descriptor model */
{
MUHWI_Descriptor_t * desc = &bgq_cq->local_completion_model;
MUSPI_DescriptorZeroOut(desc);
desc->Half_Word0.Prefetch_Only = MUHWI_DESCRIPTOR_PRE_FETCH_ONLY_NO;
desc->Half_Word1.Interrupt = MUHWI_DESCRIPTOR_DO_NOT_INTERRUPT_ON_PACKET_ARRIVAL;
desc->Pa_Payload = 0; /* specified at injection time */
desc->Message_Length = sizeof(uint64_t);
desc->Torus_FIFO_Map =
MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_LOCAL0 |
MUHWI_DESCRIPTOR_TORUS_FIFO_MAP_LOCAL1;
desc->PacketHeader.NetworkHeader.pt2pt.Data_Packet_Type = MUHWI_PT2PT_DATA_PACKET_TYPE;
desc->PacketHeader.NetworkHeader.pt2pt.Hints =
MUHWI_PACKET_HINT_A_NONE |
MUHWI_PACKET_HINT_B_NONE |
MUHWI_PACKET_HINT_C_NONE |
MUHWI_PACKET_HINT_D_NONE;
desc->PacketHeader.NetworkHeader.pt2pt.Byte2.Byte2 = 0;
desc->PacketHeader.NetworkHeader.pt2pt.Byte3.Byte3 =
MUHWI_PACKET_VIRTUAL_CHANNEL_DETERMINISTIC;
desc->PacketHeader.NetworkHeader.pt2pt.Destination.Destination.Destination = 0; /* not used for local transfers */
desc->PacketHeader.NetworkHeader.pt2pt.Byte8.Byte8 = MUHWI_PACKET_TYPE_PUT;
desc->PacketHeader.NetworkHeader.pt2pt.Byte8.Size = 16;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Rec_Payload_Base_Address_Id = FI_BGQ_MU_BAT_ID_COUNTER;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Pacing = MUHWI_PACKET_DIRECT_PUT_IS_NOT_PACED;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Put_Offset_MSB = 0;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Put_Offset_LSB = 0;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Unused1 = 0;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Rec_Counter_Base_Address_Id = FI_BGQ_MU_BAT_ID_COUNTER;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Valid_Bytes_In_Payload = 0;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Unused2 = 0;
desc->PacketHeader.messageUnitHeader.Packet_Types.Direct_Put.Counter_Offset = 0;
}
/* allocate the 'std' and 'err' l2atomic fifos */
{
struct fi_cq_bgq_l2atomic_data * memptr = NULL;
size_t bytes = sizeof(struct fi_cq_bgq_l2atomic_data) +
sizeof(uint64_t) * bgq_cq->size;
if (posix_memalign((void **)&memptr, 32, bytes)) {
errno = FI_ENOMEM;
goto err;
}
memset((void*)memptr, 0, bytes);
bgq_cq->fifo_memptr = (void*)memptr;
l2atomic_fifo_initialize(&bgq_cq->err_consumer,
&bgq_cq->err_producer,
&memptr->err_fifo_data, FI_BGQ_L2ATOMIC_ERR_FIFO_DATA_SIZE);
l2atomic_fifo_initialize(&bgq_cq->std_consumer,
&bgq_cq->std_producer,
&memptr->std_fifo_data, bgq_cq->size);
};
bgq_cq->ep_bind_count = 0;
bgq_cq->progress.ep_count = 0;
unsigned i;
for (i=0; i<64; ++i) { /* TODO - check this array size */
bgq_cq->ep[i] = NULL;
bgq_cq->progress.ep[i] = NULL;
}
fi_bgq_ref_init(&bgq_cq->domain->fabric->node, &bgq_cq->ref_cnt, "completion queue");
fi_bgq_ref_inc(&bgq_cq->domain->ref_cnt, "domain");
*cq = &bgq_cq->cq_fid;
return 0;
err:
if(bgq_cq)
free(bgq_cq);
return -errno;
}