Beispiel #1
0
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);
}
Beispiel #2
0
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);
}