diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2006-07-01 07:35:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-01 12:55:58 -0400 |
commit | 6700efdfc06d2dc9ef77988a00182c2ede0f1be0 (patch) | |
tree | a428669e9bb9b88c1dbe4192378bec454cdadfed /drivers | |
parent | 7bbb15ea8543e2e49476a27b507be3b02828a124 (diff) |
[PATCH] IB/ipath: fix shared receive queues for RC
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Cc: "Michael S. Tsirkin" <mst@mellanox.co.il>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_rc.c | 243 |
1 files changed, 101 insertions, 142 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c index 720cb3ae1fc3..bd2c405c4bf0 100644 --- a/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/drivers/infiniband/hw/ipath/ipath_rc.c | |||
@@ -257,7 +257,7 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
257 | break; | 257 | break; |
258 | 258 | ||
259 | case IB_WR_RDMA_WRITE: | 259 | case IB_WR_RDMA_WRITE: |
260 | if (newreq) | 260 | if (newreq && qp->s_lsn != (u32) -1) |
261 | qp->s_lsn++; | 261 | qp->s_lsn++; |
262 | /* FALLTHROUGH */ | 262 | /* FALLTHROUGH */ |
263 | case IB_WR_RDMA_WRITE_WITH_IMM: | 263 | case IB_WR_RDMA_WRITE_WITH_IMM: |
@@ -283,8 +283,7 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
283 | else { | 283 | else { |
284 | qp->s_state = | 284 | qp->s_state = |
285 | OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); | 285 | OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE); |
286 | /* Immediate data comes | 286 | /* Immediate data comes after RETH */ |
287 | * after RETH */ | ||
288 | ohdr->u.rc.imm_data = wqe->wr.imm_data; | 287 | ohdr->u.rc.imm_data = wqe->wr.imm_data; |
289 | hwords += 1; | 288 | hwords += 1; |
290 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) | 289 | if (wqe->wr.send_flags & IB_SEND_SOLICITED) |
@@ -304,7 +303,8 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
304 | qp->s_state = OP(RDMA_READ_REQUEST); | 303 | qp->s_state = OP(RDMA_READ_REQUEST); |
305 | hwords += sizeof(ohdr->u.rc.reth) / 4; | 304 | hwords += sizeof(ohdr->u.rc.reth) / 4; |
306 | if (newreq) { | 305 | if (newreq) { |
307 | qp->s_lsn++; | 306 | if (qp->s_lsn != (u32) -1) |
307 | qp->s_lsn++; | ||
308 | /* | 308 | /* |
309 | * Adjust s_next_psn to count the | 309 | * Adjust s_next_psn to count the |
310 | * expected number of responses. | 310 | * expected number of responses. |
@@ -335,7 +335,8 @@ int ipath_make_rc_req(struct ipath_qp *qp, | |||
335 | wqe->wr.wr.atomic.compare_add); | 335 | wqe->wr.wr.atomic.compare_add); |
336 | hwords += sizeof(struct ib_atomic_eth) / 4; | 336 | hwords += sizeof(struct ib_atomic_eth) / 4; |
337 | if (newreq) { | 337 | if (newreq) { |
338 | qp->s_lsn++; | 338 | if (qp->s_lsn != (u32) -1) |
339 | qp->s_lsn++; | ||
339 | wqe->lpsn = wqe->psn; | 340 | wqe->lpsn = wqe->psn; |
340 | } | 341 | } |
341 | if (++qp->s_cur == qp->s_size) | 342 | if (++qp->s_cur == qp->s_size) |
@@ -553,6 +554,88 @@ static void send_rc_ack(struct ipath_qp *qp) | |||
553 | } | 554 | } |
554 | 555 | ||
555 | /** | 556 | /** |
557 | * reset_psn - reset the QP state to send starting from PSN | ||
558 | * @qp: the QP | ||
559 | * @psn: the packet sequence number to restart at | ||
560 | * | ||
561 | * This is called from ipath_rc_rcv() to process an incoming RC ACK | ||
562 | * for the given QP. | ||
563 | * Called at interrupt level with the QP s_lock held. | ||
564 | */ | ||
565 | static void reset_psn(struct ipath_qp *qp, u32 psn) | ||
566 | { | ||
567 | u32 n = qp->s_last; | ||
568 | struct ipath_swqe *wqe = get_swqe_ptr(qp, n); | ||
569 | u32 opcode; | ||
570 | |||
571 | qp->s_cur = n; | ||
572 | |||
573 | /* | ||
574 | * If we are starting the request from the beginning, | ||
575 | * let the normal send code handle initialization. | ||
576 | */ | ||
577 | if (ipath_cmp24(psn, wqe->psn) <= 0) { | ||
578 | qp->s_state = OP(SEND_LAST); | ||
579 | goto done; | ||
580 | } | ||
581 | |||
582 | /* Find the work request opcode corresponding to the given PSN. */ | ||
583 | opcode = wqe->wr.opcode; | ||
584 | for (;;) { | ||
585 | int diff; | ||
586 | |||
587 | if (++n == qp->s_size) | ||
588 | n = 0; | ||
589 | if (n == qp->s_tail) | ||
590 | break; | ||
591 | wqe = get_swqe_ptr(qp, n); | ||
592 | diff = ipath_cmp24(psn, wqe->psn); | ||
593 | if (diff < 0) | ||
594 | break; | ||
595 | qp->s_cur = n; | ||
596 | /* | ||
597 | * If we are starting the request from the beginning, | ||
598 | * let the normal send code handle initialization. | ||
599 | */ | ||
600 | if (diff == 0) { | ||
601 | qp->s_state = OP(SEND_LAST); | ||
602 | goto done; | ||
603 | } | ||
604 | opcode = wqe->wr.opcode; | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * Set the state to restart in the middle of a request. | ||
609 | * Don't change the s_sge, s_cur_sge, or s_cur_size. | ||
610 | * See ipath_do_rc_send(). | ||
611 | */ | ||
612 | switch (opcode) { | ||
613 | case IB_WR_SEND: | ||
614 | case IB_WR_SEND_WITH_IMM: | ||
615 | qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
616 | break; | ||
617 | |||
618 | case IB_WR_RDMA_WRITE: | ||
619 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
620 | qp->s_state = OP(RDMA_READ_RESPONSE_LAST); | ||
621 | break; | ||
622 | |||
623 | case IB_WR_RDMA_READ: | ||
624 | qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE); | ||
625 | break; | ||
626 | |||
627 | default: | ||
628 | /* | ||
629 | * This case shouldn't happen since its only | ||
630 | * one PSN per req. | ||
631 | */ | ||
632 | qp->s_state = OP(SEND_LAST); | ||
633 | } | ||
634 | done: | ||
635 | qp->s_psn = psn; | ||
636 | } | ||
637 | |||
638 | /** | ||
556 | * ipath_restart_rc - back up requester to resend the last un-ACKed request | 639 | * ipath_restart_rc - back up requester to resend the last un-ACKed request |
557 | * @qp: the QP to restart | 640 | * @qp: the QP to restart |
558 | * @psn: packet sequence number for the request | 641 | * @psn: packet sequence number for the request |
@@ -564,7 +647,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
564 | { | 647 | { |
565 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | 648 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); |
566 | struct ipath_ibdev *dev; | 649 | struct ipath_ibdev *dev; |
567 | u32 n; | ||
568 | 650 | ||
569 | /* | 651 | /* |
570 | * If there are no requests pending, we are done. | 652 | * If there are no requests pending, we are done. |
@@ -606,62 +688,7 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc) | |||
606 | else | 688 | else |
607 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; | 689 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; |
608 | 690 | ||
609 | /* | 691 | reset_psn(qp, psn); |
610 | * If we are starting the request from the beginning, let the normal | ||
611 | * send code handle initialization. | ||
612 | */ | ||
613 | qp->s_cur = qp->s_last; | ||
614 | if (ipath_cmp24(psn, wqe->psn) <= 0) { | ||
615 | qp->s_state = OP(SEND_LAST); | ||
616 | qp->s_psn = wqe->psn; | ||
617 | } else { | ||
618 | n = qp->s_cur; | ||
619 | for (;;) { | ||
620 | if (++n == qp->s_size) | ||
621 | n = 0; | ||
622 | if (n == qp->s_tail) { | ||
623 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0) { | ||
624 | qp->s_cur = n; | ||
625 | wqe = get_swqe_ptr(qp, n); | ||
626 | } | ||
627 | break; | ||
628 | } | ||
629 | wqe = get_swqe_ptr(qp, n); | ||
630 | if (ipath_cmp24(psn, wqe->psn) < 0) | ||
631 | break; | ||
632 | qp->s_cur = n; | ||
633 | } | ||
634 | qp->s_psn = psn; | ||
635 | |||
636 | /* | ||
637 | * Reset the state to restart in the middle of a request. | ||
638 | * Don't change the s_sge, s_cur_sge, or s_cur_size. | ||
639 | * See ipath_do_rc_send(). | ||
640 | */ | ||
641 | switch (wqe->wr.opcode) { | ||
642 | case IB_WR_SEND: | ||
643 | case IB_WR_SEND_WITH_IMM: | ||
644 | qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
645 | break; | ||
646 | |||
647 | case IB_WR_RDMA_WRITE: | ||
648 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
649 | qp->s_state = OP(RDMA_READ_RESPONSE_LAST); | ||
650 | break; | ||
651 | |||
652 | case IB_WR_RDMA_READ: | ||
653 | qp->s_state = | ||
654 | OP(RDMA_READ_RESPONSE_MIDDLE); | ||
655 | break; | ||
656 | |||
657 | default: | ||
658 | /* | ||
659 | * This case shouldn't happen since its only | ||
660 | * one PSN per req. | ||
661 | */ | ||
662 | qp->s_state = OP(SEND_LAST); | ||
663 | } | ||
664 | } | ||
665 | 692 | ||
666 | done: | 693 | done: |
667 | tasklet_hi_schedule(&qp->s_task); | 694 | tasklet_hi_schedule(&qp->s_task); |
@@ -671,74 +698,12 @@ bail: | |||
671 | } | 698 | } |
672 | 699 | ||
673 | /** | 700 | /** |
674 | * reset_psn - reset the QP state to send starting from PSN | ||
675 | * @qp: the QP | ||
676 | * @psn: the packet sequence number to restart at | ||
677 | * | ||
678 | * This is called from ipath_rc_rcv_resp() to process an incoming RC ACK | ||
679 | * for the given QP. | ||
680 | * Called at interrupt level with the QP s_lock held. | ||
681 | */ | ||
682 | static void reset_psn(struct ipath_qp *qp, u32 psn) | ||
683 | { | ||
684 | struct ipath_swqe *wqe; | ||
685 | u32 n; | ||
686 | |||
687 | n = qp->s_cur; | ||
688 | wqe = get_swqe_ptr(qp, n); | ||
689 | for (;;) { | ||
690 | if (++n == qp->s_size) | ||
691 | n = 0; | ||
692 | if (n == qp->s_tail) { | ||
693 | if (ipath_cmp24(psn, qp->s_next_psn) >= 0) { | ||
694 | qp->s_cur = n; | ||
695 | wqe = get_swqe_ptr(qp, n); | ||
696 | } | ||
697 | break; | ||
698 | } | ||
699 | wqe = get_swqe_ptr(qp, n); | ||
700 | if (ipath_cmp24(psn, wqe->psn) < 0) | ||
701 | break; | ||
702 | qp->s_cur = n; | ||
703 | } | ||
704 | qp->s_psn = psn; | ||
705 | |||
706 | /* | ||
707 | * Set the state to restart in the middle of a | ||
708 | * request. Don't change the s_sge, s_cur_sge, or | ||
709 | * s_cur_size. See ipath_do_rc_send(). | ||
710 | */ | ||
711 | switch (wqe->wr.opcode) { | ||
712 | case IB_WR_SEND: | ||
713 | case IB_WR_SEND_WITH_IMM: | ||
714 | qp->s_state = OP(RDMA_READ_RESPONSE_FIRST); | ||
715 | break; | ||
716 | |||
717 | case IB_WR_RDMA_WRITE: | ||
718 | case IB_WR_RDMA_WRITE_WITH_IMM: | ||
719 | qp->s_state = OP(RDMA_READ_RESPONSE_LAST); | ||
720 | break; | ||
721 | |||
722 | case IB_WR_RDMA_READ: | ||
723 | qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE); | ||
724 | break; | ||
725 | |||
726 | default: | ||
727 | /* | ||
728 | * This case shouldn't happen since its only | ||
729 | * one PSN per req. | ||
730 | */ | ||
731 | qp->s_state = OP(SEND_LAST); | ||
732 | } | ||
733 | } | ||
734 | |||
735 | /** | ||
736 | * do_rc_ack - process an incoming RC ACK | 701 | * do_rc_ack - process an incoming RC ACK |
737 | * @qp: the QP the ACK came in on | 702 | * @qp: the QP the ACK came in on |
738 | * @psn: the packet sequence number of the ACK | 703 | * @psn: the packet sequence number of the ACK |
739 | * @opcode: the opcode of the request that resulted in the ACK | 704 | * @opcode: the opcode of the request that resulted in the ACK |
740 | * | 705 | * |
741 | * This is called from ipath_rc_rcv() to process an incoming RC ACK | 706 | * This is called from ipath_rc_rcv_resp() to process an incoming RC ACK |
742 | * for the given QP. | 707 | * for the given QP. |
743 | * Called at interrupt level with the QP s_lock held. | 708 | * Called at interrupt level with the QP s_lock held. |
744 | * Returns 1 if OK, 0 if current operation should be aborted (NAK). | 709 | * Returns 1 if OK, 0 if current operation should be aborted (NAK). |
@@ -877,22 +842,12 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode) | |||
877 | if (qp->s_last == qp->s_tail) | 842 | if (qp->s_last == qp->s_tail) |
878 | goto bail; | 843 | goto bail; |
879 | 844 | ||
880 | /* The last valid PSN seen is the previous request's. */ | 845 | /* The last valid PSN is the previous PSN. */ |
881 | qp->s_last_psn = wqe->psn - 1; | 846 | qp->s_last_psn = psn - 1; |
882 | 847 | ||
883 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; | 848 | dev->n_rc_resends += (int)qp->s_psn - (int)psn; |
884 | 849 | ||
885 | /* | 850 | reset_psn(qp, psn); |
886 | * If we are starting the request from the beginning, let | ||
887 | * the normal send code handle initialization. | ||
888 | */ | ||
889 | qp->s_cur = qp->s_last; | ||
890 | wqe = get_swqe_ptr(qp, qp->s_cur); | ||
891 | if (ipath_cmp24(psn, wqe->psn) <= 0) { | ||
892 | qp->s_state = OP(SEND_LAST); | ||
893 | qp->s_psn = wqe->psn; | ||
894 | } else | ||
895 | reset_psn(qp, psn); | ||
896 | 851 | ||
897 | qp->s_rnr_timeout = | 852 | qp->s_rnr_timeout = |
898 | ib_ipath_rnr_table[(aeth >> IPS_AETH_CREDIT_SHIFT) & | 853 | ib_ipath_rnr_table[(aeth >> IPS_AETH_CREDIT_SHIFT) & |
@@ -1070,9 +1025,10 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, | |||
1070 | &dev->pending[dev->pending_index]); | 1025 | &dev->pending[dev->pending_index]); |
1071 | spin_unlock(&dev->pending_lock); | 1026 | spin_unlock(&dev->pending_lock); |
1072 | /* | 1027 | /* |
1073 | * Update the RDMA receive state but do the copy w/o holding the | 1028 | * Update the RDMA receive state but do the copy w/o |
1074 | * locks and blocking interrupts. XXX Yet another place that | 1029 | * holding the locks and blocking interrupts. |
1075 | * affects relaxed RDMA order since we don't want s_sge modified. | 1030 | * XXX Yet another place that affects relaxed RDMA order |
1031 | * since we don't want s_sge modified. | ||
1076 | */ | 1032 | */ |
1077 | qp->s_len -= pmtu; | 1033 | qp->s_len -= pmtu; |
1078 | qp->s_last_psn = psn; | 1034 | qp->s_last_psn = psn; |
@@ -1119,9 +1075,12 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, | |||
1119 | if (do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST))) { | 1075 | if (do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST))) { |
1120 | /* | 1076 | /* |
1121 | * Change the state so we contimue | 1077 | * Change the state so we contimue |
1122 | * processing new requests. | 1078 | * processing new requests and wake up the |
1079 | * tasklet if there are posted sends. | ||
1123 | */ | 1080 | */ |
1124 | qp->s_state = OP(SEND_LAST); | 1081 | qp->s_state = OP(SEND_LAST); |
1082 | if (qp->s_tail != qp->s_head) | ||
1083 | tasklet_hi_schedule(&qp->s_task); | ||
1125 | } | 1084 | } |
1126 | goto ack_done; | 1085 | goto ack_done; |
1127 | } | 1086 | } |