Dnode * _elf_dnode() { register Dnode *d; if ((d = (Dnode *)malloc(sizeof (Dnode))) == 0) { _elf_seterr(EMEM_DNODE, errno); return (0); } NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*d)) *d = _elf_dnode_init; d->db_myflags = DBF_ALLOC; NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*d)) return (d); }
Elf * _elf_regular(int fd, unsigned flags) /* initialize regular file */ { Elf *elf; if ((elf = (Elf *)calloc(1, sizeof (Elf))) == 0) { _elf_seterr(EMEM_ELF, errno); return (0); } NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*elf)) elf->ed_fd = fd; elf->ed_myflags |= flags; if (_elf_inmap(elf) != OK_YES) { free(elf); return (0); } NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*elf)) return (elf); }
/* * ibmf_i_issue_pkt(): * Post an IB packet on the specified QP's send queue */ int ibmf_i_issue_pkt(ibmf_client_t *clientp, ibmf_msg_impl_t *msgimplp, ibmf_qp_handle_t ibmf_qp_handle, ibmf_send_wqe_t *send_wqep) { int ret; ibt_status_t status; ibt_wr_ds_t sgl[1]; ibt_qp_hdl_t ibt_qp_handle; _NOTE(ASSUMING_PROTECTED(*send_wqep)) _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*send_wqep)) IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_issue_pkt_start, IBMF_TNF_TRACE, "", "ibmf_i_issue_pkt() enter, clientp = %p, msg = %p, " "qp_hdl = %p, swqep = %p\n", tnf_opaque, clientp, clientp, tnf_opaque, msg, msgimplp, tnf_opaque, ibmf_qp_handle, ibmf_qp_handle, tnf_opaque, send_wqep, send_wqep); ASSERT(MUTEX_HELD(&msgimplp->im_mutex)); ASSERT(MUTEX_NOT_HELD(&clientp->ic_mutex)); /* * if the qp handle provided in ibmf_send_pkt() * is not the default qp handle for this client, * then the wqe must be sent on this qp, * else use the default qp handle set up during ibmf_register() */ if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) { ibt_qp_handle = clientp->ic_qp->iq_qp_handle; } else { ibt_qp_handle = ((ibmf_alt_qp_t *)ibmf_qp_handle)->isq_qp_handle; } /* initialize the send WQE */ ibmf_i_init_send_wqe(clientp, msgimplp, sgl, send_wqep, msgimplp->im_ud_dest, ibt_qp_handle, ibmf_qp_handle); _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*send_wqep)) /* * Issue the wqe to the transport. * NOTE: ibt_post_send() will not block, so, it is ok * to hold the msgimpl mutex across this call. */ status = ibt_post_send(send_wqep->send_qp_handle, &send_wqep->send_wr, 1, NULL); if (status != IBT_SUCCESS) { mutex_enter(&clientp->ic_kstat_mutex); IBMF_ADD32_KSTATS(clientp, send_pkt_failed, 1); mutex_exit(&clientp->ic_kstat_mutex); IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1, ibmf_i_issue_pkt_err, IBMF_TNF_TRACE, "", "ibmf_i_issue_pkt(): %s, status = %d\n", tnf_string, msg, "post send failure", tnf_uint, ibt_status, status); IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_issue_pkt_end, IBMF_TNF_TRACE, "", "ibmf_i_issue_pkt(() exit\n"); return (IBMF_TRANSPORT_FAILURE); } ret = IBMF_SUCCESS; /* bump the number of active sends */ if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) { mutex_enter(&clientp->ic_mutex); clientp->ic_sends_active++; mutex_exit(&clientp->ic_mutex); mutex_enter(&clientp->ic_kstat_mutex); IBMF_ADD32_KSTATS(clientp, sends_active, 1); mutex_exit(&clientp->ic_kstat_mutex); } else { ibmf_alt_qp_t *qpp = (ibmf_alt_qp_t *)ibmf_qp_handle; mutex_enter(&qpp->isq_mutex); qpp->isq_sends_active++; mutex_exit(&qpp->isq_mutex); mutex_enter(&clientp->ic_kstat_mutex); IBMF_ADD32_KSTATS(clientp, sends_active, 1); mutex_exit(&clientp->ic_kstat_mutex); } IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_issue_pkt_end, IBMF_TNF_TRACE, "", "ibmf_i_issue_pkt() exit\n"); return (ret); }
/* ARGSUSED */ void ibmf_i_handle_send_completion(ibmf_ci_t *cip, ibt_wc_t *wcp) { ibmf_client_t *clientp, *cclientp; ibmf_send_wqe_t *send_wqep; ibmf_qp_handle_t ibmf_qp_handle; ibmf_alt_qp_t *qpp; int ret; IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_completion_start, IBMF_TNF_TRACE, "", "ibmf_i_handle_send_completion() enter, cip = %p, wcp = %p\n", tnf_opaque, cip, cip, tnf_opaque, wcp, wcp); _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*send_wqep)) ASSERT(wcp->wc_id != NULL); ASSERT(IBMF_IS_SEND_WR_ID(wcp->wc_id)); /* get the IBMF send WQE context */ IBMF_SEND_WR_ID_TO_ADDR(wcp->wc_id, send_wqep); ASSERT(send_wqep != NULL); /* get the client context */ cclientp = clientp = send_wqep->send_client; /* Check if this is a completion for a BUSY MAD sent by IBMF */ if (clientp == NULL) { ibmf_msg_impl_t *msgimplp; IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L3, ibmf_i_handle_send_completion, IBMF_TNF_TRACE, "", "ibmf_i_handle_send_completion(): NULL client\n"); msgimplp = send_wqep->send_msg; /* * Deregister registered memory and free it, and * free up the send WQE context */ (void) ibt_deregister_mr(cip->ci_ci_handle, send_wqep->send_mem_hdl); kmem_free(send_wqep->send_mem, IBMF_MEM_PER_WQE); kmem_free(send_wqep, sizeof (ibmf_send_wqe_t)); /* Free up the message context */ ibmf_i_put_ud_dest(cip, msgimplp->im_ibmf_ud_dest); ibmf_i_clean_ud_dest_list(cip, B_FALSE); kmem_free(msgimplp, sizeof (ibmf_msg_impl_t)); IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_completion_end, IBMF_TNF_TRACE, "", "ibmf_i_handle_send_completion() exit\n"); return; } /* get the QP handle */ ibmf_qp_handle = send_wqep->send_ibmf_qp_handle; qpp = (ibmf_alt_qp_t *)ibmf_qp_handle; ASSERT(clientp != NULL); /* decrement the number of active sends */ if (ibmf_qp_handle == IBMF_QP_HANDLE_DEFAULT) { mutex_enter(&clientp->ic_mutex); clientp->ic_sends_active--; mutex_exit(&clientp->ic_mutex); } else { mutex_enter(&qpp->isq_mutex); qpp->isq_sends_active--; mutex_exit(&qpp->isq_mutex); } mutex_enter(&clientp->ic_kstat_mutex); IBMF_SUB32_KSTATS(clientp, sends_active, 1); mutex_exit(&clientp->ic_kstat_mutex); send_wqep->send_status = ibmf_i_ibt_wc_to_ibmf_status(wcp->wc_status); /* * issue the callback using taskq. If no taskq or if the * dispatch fails, we do the send processing in the callback context * which is the interrupt context */ if (cclientp->ic_send_taskq == NULL) { /* Do the processing in callback context */ mutex_enter(&clientp->ic_kstat_mutex); IBMF_ADD32_KSTATS(clientp, send_cb_active, 1); mutex_exit(&clientp->ic_kstat_mutex); ibmf_i_do_send_cb((void *)send_wqep); mutex_enter(&clientp->ic_kstat_mutex); IBMF_SUB32_KSTATS(clientp, send_cb_active, 1); mutex_exit(&clientp->ic_kstat_mutex); IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_err, IBMF_TNF_ERROR, "", "ibmf_i_handle_send_completion(): %s\n", tnf_string, msg, "ci_send_taskq == NULL"); IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_completion_end, IBMF_TNF_TRACE, "", "ibmf_i_handle_send_completion() exit\n"); return; } mutex_enter(&clientp->ic_kstat_mutex); IBMF_ADD32_KSTATS(clientp, send_cb_active, 1); mutex_exit(&clientp->ic_kstat_mutex); /* Use taskq for processing if the IBMF_REG_FLAG_NO_OFFLOAD isn't set */ if ((clientp->ic_reg_flags & IBMF_REG_FLAG_NO_OFFLOAD) == 0) { ret = taskq_dispatch(cclientp->ic_send_taskq, ibmf_i_do_send_cb, send_wqep, TQ_NOSLEEP); if (ret == 0) { IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_err, IBMF_TNF_ERROR, "", "ibmf_i_handle_send_completion(): %s\n", tnf_string, msg, "send: dispatch failed"); ibmf_i_do_send_cb((void *)send_wqep); } } else { ibmf_i_do_send_cb((void *)send_wqep); } mutex_enter(&clientp->ic_kstat_mutex); IBMF_SUB32_KSTATS(clientp, send_cb_active, 1); mutex_exit(&clientp->ic_kstat_mutex); _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*send_wqep)) IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_handle_send_completion_end, IBMF_TNF_TRACE, "", "ibmf_i_handle_send_completion() exit\n"); }
/* * ibmf_i_send_pkt() * Send an IB packet after allocating send resources */ int ibmf_i_send_pkt(ibmf_client_t *clientp, ibmf_qp_handle_t ibmf_qp_handle, ibmf_msg_impl_t *msgimplp, int block) { ibmf_send_wqe_t *send_wqep; int status; IBMF_TRACE_4(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_send_pkt_start, IBMF_TNF_TRACE, "", "ibmf_i_send_pkt(): clientp = 0x%p, qp_hdl = 0x%p, " "msgp = 0x%p, block = %d\n", tnf_opaque, clientp, clientp, tnf_opaque, qp_hdl, ibmf_qp_handle, tnf_opaque, msg, msgimplp, tnf_uint, block, block); ASSERT(MUTEX_HELD(&msgimplp->im_mutex)); _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*send_wqep)) /* * Reset send_done to indicate we have not received the completion * for this send yet. */ msgimplp->im_trans_state_flags &= ~IBMF_TRANS_STATE_FLAG_SEND_DONE; /* * Allocate resources needed to send a UD packet including the * send WQE context */ status = ibmf_i_alloc_send_resources(clientp->ic_myci, msgimplp, block, &send_wqep); if (status != IBMF_SUCCESS) { IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1, ibmf_i_send_pkt_err, IBMF_TNF_ERROR, "", "ibmf_i_send_pkt(): %s, status = %d\n", tnf_string, msg, "unable to allocate send resources", tnf_uint, status, status); IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_send_pkt_end, IBMF_TNF_TRACE, "", "ibmf_i_send_pkt() exit\n"); return (status); } /* Set the segment number in the send WQE context */ if (msgimplp->im_flags & IBMF_MSG_FLAGS_SEND_RMPP) send_wqep->send_rmpp_segment = msgimplp->im_rmpp_ctx.rmpp_ns; _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*send_wqep)) /* * Increment the count of pending send completions. * Only when this count is zero should the client be notified * of completion of the transaction. */ msgimplp->im_pending_send_compls += 1; /* Send the packet */ status = ibmf_i_issue_pkt(clientp, msgimplp, ibmf_qp_handle, send_wqep); if (status != IBMF_SUCCESS) { ibmf_i_free_send_resources(clientp->ic_myci, msgimplp, send_wqep); IBMF_TRACE_2(IBMF_TNF_NODEBUG, DPRINT_L1, ibmf_i_send_pkt_err, IBMF_TNF_ERROR, "", "ibmf_i_send_pkt(): %s, status = %d\n", tnf_string, msg, "unable to issue packet", tnf_uint, status, status); IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_send_pkt_end, IBMF_TNF_TRACE, "", "ibmf_i_send_pkt() exit\n"); return (status); } IBMF_TRACE_1(IBMF_TNF_DEBUG, DPRINT_L4, ibmf_i_send_pkt_end, IBMF_TNF_TRACE, "", "ibmf_i_send_pkt() exit, status = %d\n", tnf_uint, status, status); return (IBMF_SUCCESS); }