示例#1
0
/*
 * Keep progressing sends on this queue until:
 * a) no more send credits on the queue (it's full)
 * or
 * b) all endpoints are complete or blocked awaiting ACKs
 */
void
usdf_msg_tx_progress(struct usdf_tx *tx)
{
	struct usdf_ep *ep;
	struct usd_qp_impl *qp;

	qp = to_qpi(tx->tx_qp);
	while (qp->uq_wq.uwq_send_credits > 1 &&
			!TAILQ_EMPTY(&tx->t.msg.tx_ep_have_acks)) {
		ep = TAILQ_FIRST(&tx->t.msg.tx_ep_have_acks);
		TAILQ_REMOVE_MARK(&tx->t.msg.tx_ep_have_acks,
				ep, e.msg.ep_ack_link);

		usdf_msg_send_ack(tx, ep);
	}

	while (qp->uq_wq.uwq_send_credits > 1 &&
			!TAILQ_EMPTY(&tx->t.msg.tx_ep_ready)) {
		ep = TAILQ_FIRST(&tx->t.msg.tx_ep_ready);

		/*
		 * Send next segment on this EP. This will also remove the
		 * current send from the EP send list if it completes
		 */
		usdf_msg_send_segment(tx, ep);

		--ep->e.msg.ep_seq_credits;
		if (TAILQ_EMPTY(&ep->e.msg.ep_posted_wqe)) {
			TAILQ_REMOVE_MARK(&tx->t.msg.tx_ep_ready,
					ep, e.msg.ep_link);
		} else {
			--ep->e.msg.ep_fairness_credits;
			if (ep->e.msg.ep_seq_credits == 0) {
				TAILQ_REMOVE_MARK(&tx->t.msg.tx_ep_ready,
						ep, e.msg.ep_link);
				ep->e.msg.ep_fairness_credits =
					USDF_MSG_FAIRNESS_CREDITS;

			/* fairness credits exhausted, go to back of the line */
			} else if (ep->e.msg.ep_fairness_credits == 0) {
				TAILQ_REMOVE(&tx->t.msg.tx_ep_ready,
						ep, e.msg.ep_link);
				TAILQ_INSERT_TAIL(&tx->t.msg.tx_ep_ready,
						ep, e.msg.ep_link);
				ep->e.msg.ep_fairness_credits =
					USDF_MSG_FAIRNESS_CREDITS;
			}
		}
	}
}
示例#2
0
static int
usdf_pep_listen_cb(void *v)
{
    struct usdf_pep *pep;
    struct sockaddr_in sin;
    struct usdf_connreq *crp;
    struct epoll_event ev;
    socklen_t socklen;
    int ret;
    int s;

    pep = v;

    socklen = sizeof(sin);
    s = accept(pep->pep_sock, &sin, &socklen);
    if (s == -1) {
        /* ignore early failure */
        return 0;
    }
    crp = NULL;
    pthread_spin_lock(&pep->pep_cr_lock);
    if (!TAILQ_EMPTY(&pep->pep_cr_free)) {
        crp = TAILQ_FIRST(&pep->pep_cr_free);
        TAILQ_REMOVE_MARK(&pep->pep_cr_free, crp, cr_link);
        TAILQ_NEXT(crp, cr_link) = NULL;
    }
    pthread_spin_unlock(&pep->pep_cr_lock);

    /* no room for request, just drop it */
    if (crp == NULL) {
        /* XXX send response? */
        close(s);
        return 0;
    }

    crp->cr_sockfd = s;
    crp->cr_pep = pep;
    crp->cr_ptr = crp->cr_data;
    crp->cr_resid = sizeof(struct usdf_connreq_msg);

    crp->cr_pollitem.pi_rtn = usdf_pep_read_connreq;
    crp->cr_pollitem.pi_context = crp;
    ev.events = EPOLLIN;
    ev.data.ptr = &crp->cr_pollitem;

    ret = epoll_ctl(pep->pep_fabric->fab_epollfd, EPOLL_CTL_ADD,
                    crp->cr_sockfd, &ev);
    if (ret == -1) {
        crp->cr_pollitem.pi_rtn = NULL;
        usdf_cm_msg_connreq_failed(crp, -errno);
        return 0;
    }

    TAILQ_INSERT_TAIL(&pep->pep_cr_pending, crp, cr_link);

    return 0;
}