aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan O'Sullivan <bos@pathscale.com>2006-04-24 17:23:06 -0400
committerRoland Dreier <rolandd@cisco.com>2006-05-01 15:14:21 -0400
commit9b2017f1e1c95625b2ca2a1ec5317097117d7078 (patch)
tree2f799016e4f05348ddf6e01d71993c08fd5b0a0f
parent76f0dd141b477094b026206c0d8c21beac6069f5 (diff)
IB/ipath: simplify IB timer usage
Signed-off-by: Bryan O'Sullivan <bos@pathscale.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c39
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.h3
2 files changed, 12 insertions, 30 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 8d2558a01f35..cb9e387c301f 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -449,7 +449,6 @@ static void ipath_ib_timer(void *arg)
449{ 449{
450 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg; 450 struct ipath_ibdev *dev = (struct ipath_ibdev *) arg;
451 struct ipath_qp *resend = NULL; 451 struct ipath_qp *resend = NULL;
452 struct ipath_qp *rnr = NULL;
453 struct list_head *last; 452 struct list_head *last;
454 struct ipath_qp *qp; 453 struct ipath_qp *qp;
455 unsigned long flags; 454 unsigned long flags;
@@ -465,32 +464,18 @@ static void ipath_ib_timer(void *arg)
465 last = &dev->pending[dev->pending_index]; 464 last = &dev->pending[dev->pending_index];
466 while (!list_empty(last)) { 465 while (!list_empty(last)) {
467 qp = list_entry(last->next, struct ipath_qp, timerwait); 466 qp = list_entry(last->next, struct ipath_qp, timerwait);
468 if (last->next == LIST_POISON1 || 467 list_del(&qp->timerwait);
469 last->next != &qp->timerwait || 468 qp->timer_next = resend;
470 qp->timerwait.prev != last) { 469 resend = qp;
471 INIT_LIST_HEAD(last); 470 atomic_inc(&qp->refcount);
472 } else {
473 list_del(&qp->timerwait);
474 qp->timerwait.prev = (struct list_head *) resend;
475 resend = qp;
476 atomic_inc(&qp->refcount);
477 }
478 } 471 }
479 last = &dev->rnrwait; 472 last = &dev->rnrwait;
480 if (!list_empty(last)) { 473 if (!list_empty(last)) {
481 qp = list_entry(last->next, struct ipath_qp, timerwait); 474 qp = list_entry(last->next, struct ipath_qp, timerwait);
482 if (--qp->s_rnr_timeout == 0) { 475 if (--qp->s_rnr_timeout == 0) {
483 do { 476 do {
484 if (last->next == LIST_POISON1 ||
485 last->next != &qp->timerwait ||
486 qp->timerwait.prev != last) {
487 INIT_LIST_HEAD(last);
488 break;
489 }
490 list_del(&qp->timerwait); 477 list_del(&qp->timerwait);
491 qp->timerwait.prev = 478 tasklet_hi_schedule(&qp->s_task);
492 (struct list_head *) rnr;
493 rnr = qp;
494 if (list_empty(last)) 479 if (list_empty(last))
495 break; 480 break;
496 qp = list_entry(last->next, struct ipath_qp, 481 qp = list_entry(last->next, struct ipath_qp,
@@ -530,8 +515,7 @@ static void ipath_ib_timer(void *arg)
530 spin_unlock_irqrestore(&dev->pending_lock, flags); 515 spin_unlock_irqrestore(&dev->pending_lock, flags);
531 516
532 /* XXX What if timer fires again while this is running? */ 517 /* XXX What if timer fires again while this is running? */
533 for (qp = resend; qp != NULL; 518 for (qp = resend; qp != NULL; qp = qp->timer_next) {
534 qp = (struct ipath_qp *) qp->timerwait.prev) {
535 struct ib_wc wc; 519 struct ib_wc wc;
536 520
537 spin_lock_irqsave(&qp->s_lock, flags); 521 spin_lock_irqsave(&qp->s_lock, flags);
@@ -545,9 +529,6 @@ static void ipath_ib_timer(void *arg)
545 if (atomic_dec_and_test(&qp->refcount)) 529 if (atomic_dec_and_test(&qp->refcount))
546 wake_up(&qp->wait); 530 wake_up(&qp->wait);
547 } 531 }
548 for (qp = rnr; qp != NULL;
549 qp = (struct ipath_qp *) qp->timerwait.prev)
550 tasklet_hi_schedule(&qp->s_task);
551} 532}
552 533
553/** 534/**
@@ -556,9 +537,9 @@ static void ipath_ib_timer(void *arg)
556 * 537 *
557 * This is called from ipath_intr() at interrupt level when a PIO buffer is 538 * This is called from ipath_intr() at interrupt level when a PIO buffer is
558 * available after ipath_verbs_send() returned an error that no buffers were 539 * available after ipath_verbs_send() returned an error that no buffers were
559 * available. Return 0 if we consumed all the PIO buffers and we still have 540 * available. Return 1 if we consumed all the PIO buffers and we still have
560 * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and 541 * QPs waiting for buffers (for now, just do a tasklet_hi_schedule and
561 * return one). 542 * return zero).
562 */ 543 */
563static int ipath_ib_piobufavail(void *arg) 544static int ipath_ib_piobufavail(void *arg)
564{ 545{
@@ -579,7 +560,7 @@ static int ipath_ib_piobufavail(void *arg)
579 spin_unlock_irqrestore(&dev->pending_lock, flags); 560 spin_unlock_irqrestore(&dev->pending_lock, flags);
580 561
581bail: 562bail:
582 return 1; 563 return 0;
583} 564}
584 565
585static int ipath_query_device(struct ib_device *ibdev, 566static int ipath_query_device(struct ib_device *ibdev,
@@ -1159,7 +1140,7 @@ static ssize_t show_stats(struct class_device *cdev, char *buf)
1159 1140
1160 len = sprintf(buf, 1141 len = sprintf(buf,
1161 "RC resends %d\n" 1142 "RC resends %d\n"
1162 "RC QACKs %d\n" 1143 "RC no QACK %d\n"
1163 "RC ACKs %d\n" 1144 "RC ACKs %d\n"
1164 "RC SEQ NAKs %d\n" 1145 "RC SEQ NAKs %d\n"
1165 "RC RDMA seq %d\n" 1146 "RC RDMA seq %d\n"
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h
index fcafbc7c9e71..4f8d59300e9b 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.h
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.h
@@ -282,7 +282,8 @@ struct ipath_srq {
282 */ 282 */
283struct ipath_qp { 283struct ipath_qp {
284 struct ib_qp ibqp; 284 struct ib_qp ibqp;
285 struct ipath_qp *next; /* link list for QPN hash table */ 285 struct ipath_qp *next; /* link list for QPN hash table */
286 struct ipath_qp *timer_next; /* link list for ipath_ib_timer() */
286 struct list_head piowait; /* link for wait PIO buf */ 287 struct list_head piowait; /* link for wait PIO buf */
287 struct list_head timerwait; /* link for waiting for timeouts */ 288 struct list_head timerwait; /* link for waiting for timeouts */
288 struct ib_ah_attr remote_ah_attr; 289 struct ib_ah_attr remote_ah_attr;