IB/qib: Precompute timeout jiffies to optimize latency

A new field is added to qib_qp called timeout_jiffies. It is
initialized upon create and modify.

The field is now used instead of a computation based on qp->timeout.

Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
This commit is contained in:
Mike Marciniszyn 2011-09-23 13:16:49 -04:00 committed by Roland Dreier
parent af061a644a
commit d0f2faf72d
3 changed files with 11 additions and 6 deletions

View File

@ -801,8 +801,12 @@ int qib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
if (attr_mask & IB_QP_MIN_RNR_TIMER) if (attr_mask & IB_QP_MIN_RNR_TIMER)
qp->r_min_rnr_timer = attr->min_rnr_timer; qp->r_min_rnr_timer = attr->min_rnr_timer;
if (attr_mask & IB_QP_TIMEOUT) if (attr_mask & IB_QP_TIMEOUT) {
qp->timeout = attr->timeout; qp->timeout = attr->timeout;
qp->timeout_jiffies =
usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
1000UL);
}
if (attr_mask & IB_QP_QKEY) if (attr_mask & IB_QP_QKEY)
qp->qkey = attr->qkey; qp->qkey = attr->qkey;
@ -1034,6 +1038,9 @@ struct ib_qp *qib_create_qp(struct ib_pd *ibpd,
goto bail_swq; goto bail_swq;
} }
RCU_INIT_POINTER(qp->next, NULL); RCU_INIT_POINTER(qp->next, NULL);
qp->timeout_jiffies =
usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
1000UL);
if (init_attr->srq) if (init_attr->srq)
sz = 0; sz = 0;
else { else {

View File

@ -59,8 +59,7 @@ static void start_timer(struct qib_qp *qp)
qp->s_flags |= QIB_S_TIMER; qp->s_flags |= QIB_S_TIMER;
qp->s_timer.function = rc_timeout; qp->s_timer.function = rc_timeout;
/* 4.096 usec. * (1 << qp->timeout) */ /* 4.096 usec. * (1 << qp->timeout) */
qp->s_timer.expires = jiffies + qp->s_timer.expires = jiffies + qp->timeout_jiffies;
usecs_to_jiffies((4096UL * (1UL << qp->timeout)) / 1000UL);
add_timer(&qp->s_timer); add_timer(&qp->s_timer);
} }
@ -1519,9 +1518,7 @@ read_middle:
* 4.096 usec. * (1 << qp->timeout) * 4.096 usec. * (1 << qp->timeout)
*/ */
qp->s_flags |= QIB_S_TIMER; qp->s_flags |= QIB_S_TIMER;
mod_timer(&qp->s_timer, jiffies + mod_timer(&qp->s_timer, jiffies + qp->timeout_jiffies);
usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
1000UL));
if (qp->s_flags & QIB_S_WAIT_ACK) { if (qp->s_flags & QIB_S_WAIT_ACK) {
qp->s_flags &= ~QIB_S_WAIT_ACK; qp->s_flags &= ~QIB_S_WAIT_ACK;
qib_schedule_send(qp); qib_schedule_send(qp);

View File

@ -496,6 +496,7 @@ struct qib_qp {
u32 s_last; /* last completed entry */ u32 s_last; /* last completed entry */
u32 s_ssn; /* SSN of tail entry */ u32 s_ssn; /* SSN of tail entry */
u32 s_lsn; /* limit sequence number (credit) */ u32 s_lsn; /* limit sequence number (credit) */
unsigned long timeout_jiffies; /* computed from timeout */
struct qib_swqe *s_wq; /* send work queue */ struct qib_swqe *s_wq; /* send work queue */
struct qib_swqe *s_wqe; struct qib_swqe *s_wqe;
struct qib_rq r_rq; /* receive work queue */ struct qib_rq r_rq; /* receive work queue */