static int __gnix_amo_txd_complete(void *arg, gni_return_t tx_status) { struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg; struct gnix_fab_req *req = txd->req; int rc = FI_SUCCESS; _gnix_nic_tx_free(req->vc->ep->nic, txd); if (tx_status != GNI_RC_SUCCESS) { return __gnix_amo_post_err(req, FI_ECANCELED); } if (req->vc->peer_caps & FI_RMA_EVENT) { /* control message needed for a counter event. */ req->work_fn = __gnix_amo_send_cntr_req; _gnix_vc_queue_work_req(req); } else { /* complete request */ rc = __gnix_amo_send_completion(req->vc->ep, req); if (rc != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_DATA, "__gnix_amo_send_completion() failed: %d\n", rc); __gnix_amo_fr_complete(req); } return FI_SUCCESS; }
static int __gnix_amo_post_err(struct gnix_fab_req *req, int error) { int rc; rc = __gnix_amo_send_err(req->vc->ep, req, error); if (rc != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_DATA, "__gnix_amo_send_err() failed: %d\n", rc); __gnix_amo_fr_complete(req); return FI_SUCCESS; }
static int __gnix_amo_post_err(struct gnix_tx_descriptor *txd) { struct gnix_fab_req *req = txd->req; int rc; rc = __gnix_amo_send_err(req->vc->ep, req); if (rc != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_DATA, "__gnix_amo_send_err() failed: %d\n", rc); __gnix_amo_fr_complete(req, txd); return FI_SUCCESS; }
static int __gnix_amo_txd_complete(void *arg, gni_return_t tx_status) { struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg; struct gnix_fab_req *req = txd->req; int rc = FI_SUCCESS; uint32_t read_data32; uint64_t read_data64; if (tx_status != GNI_RC_SUCCESS) { return __gnix_amo_post_err(txd); } /* FI_ATOMIC_READ data is delivered to operand buffer in addition to * the results buffer. */ if (req->amo.op == FI_ATOMIC_READ) { switch(fi_datatype_size(req->amo.datatype)) { case sizeof(uint32_t): read_data32 = *(uint32_t *)req->amo.loc_addr; *(uint32_t *)req->amo.read_buf = read_data32; break; case sizeof(uint64_t): read_data64 = *(uint64_t *)req->amo.loc_addr; *(uint64_t *)req->amo.read_buf = read_data64; break; default: GNIX_WARN(FI_LOG_EP_DATA, "Invalid datatype: %d\n", req->amo.datatype); assert(0); break; } } /* complete request */ rc = __gnix_amo_send_completion(req->vc->ep, req); if (rc != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_DATA, "__gnix_amo_send_completion() failed: %d\n", rc); __gnix_amo_fr_complete(req, txd); return FI_SUCCESS; }
static int __gnix_amo_txd_cntr_complete(void *arg, gni_return_t tx_status) { struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg; struct gnix_fab_req *req = txd->req; int rc; _gnix_nic_tx_free(req->gnix_ep->nic, txd); if (tx_status != GNI_RC_SUCCESS) return __gnix_amo_post_err(req, FI_ECANCELED); /* Successful data delivery. Generate local completion. */ rc = __gnix_amo_send_completion(req->vc->ep, req); if (rc != FI_SUCCESS) GNIX_WARN(FI_LOG_EP_DATA, "__gnix_amo_send_completion() failed: %d\n", rc); __gnix_amo_fr_complete(req); return FI_SUCCESS; }