diff options
author | Mike Marciniszyn <mike.marciniszyn@intel.com> | 2018-05-01 08:35:51 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2018-05-03 15:24:47 -0400 |
commit | 0a0bcb046b2f0c15b89f8c1b08ad3de601a83c66 (patch) | |
tree | cfcf1960fc9336bb087cab584190814d50e2ddf3 | |
parent | 5da9e742be44d9b7c68b1bf6e1aaf46a1aa7a52b (diff) |
IB/hfi1: Fix loss of BECN with AHG
AHG may be armed to use the stored header, which by design is limited
to edits in the PSN/A 32 bit word (bth2).
When the code is trying to send a BECN, the use of the stored header
will lose the BECN bit.
Fix by avoiding AHG when getting ready to send a BECN. This is
accomplished by always claiming the packet is not a middle packet which
is an AHG precursor. BECNs are not a normal case and this should not
hurt AHG optimizations.
Cc: <stable@vger.kernel.org> # 4.14.x
Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/hw/hfi1/ruc.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c index 3daa94bdae3a..c0071ca4147a 100644 --- a/drivers/infiniband/hw/hfi1/ruc.c +++ b/drivers/infiniband/hw/hfi1/ruc.c | |||
@@ -733,6 +733,20 @@ static inline void hfi1_make_ruc_bth(struct rvt_qp *qp, | |||
733 | ohdr->bth[2] = cpu_to_be32(bth2); | 733 | ohdr->bth[2] = cpu_to_be32(bth2); |
734 | } | 734 | } |
735 | 735 | ||
736 | /** | ||
737 | * hfi1_make_ruc_header_16B - build a 16B header | ||
738 | * @qp: the queue pair | ||
739 | * @ohdr: a pointer to the destination header memory | ||
740 | * @bth0: bth0 passed in from the RC/UC builder | ||
741 | * @bth2: bth2 passed in from the RC/UC builder | ||
742 | * @middle: non zero implies indicates ahg "could" be used | ||
743 | * @ps: the current packet state | ||
744 | * | ||
745 | * This routine may disarm ahg under these situations: | ||
746 | * - packet needs a GRH | ||
747 | * - BECN needed | ||
748 | * - migration state not IB_MIG_MIGRATED | ||
749 | */ | ||
736 | static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | 750 | static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, |
737 | struct ib_other_headers *ohdr, | 751 | struct ib_other_headers *ohdr, |
738 | u32 bth0, u32 bth2, int middle, | 752 | u32 bth0, u32 bth2, int middle, |
@@ -777,6 +791,12 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
777 | else | 791 | else |
778 | middle = 0; | 792 | middle = 0; |
779 | 793 | ||
794 | if (qp->s_flags & RVT_S_ECN) { | ||
795 | qp->s_flags &= ~RVT_S_ECN; | ||
796 | /* we recently received a FECN, so return a BECN */ | ||
797 | becn = true; | ||
798 | middle = 0; | ||
799 | } | ||
780 | if (middle) | 800 | if (middle) |
781 | build_ahg(qp, bth2); | 801 | build_ahg(qp, bth2); |
782 | else | 802 | else |
@@ -784,11 +804,6 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
784 | 804 | ||
785 | bth0 |= pkey; | 805 | bth0 |= pkey; |
786 | bth0 |= extra_bytes << 20; | 806 | bth0 |= extra_bytes << 20; |
787 | if (qp->s_flags & RVT_S_ECN) { | ||
788 | qp->s_flags &= ~RVT_S_ECN; | ||
789 | /* we recently received a FECN, so return a BECN */ | ||
790 | becn = true; | ||
791 | } | ||
792 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); | 807 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
793 | 808 | ||
794 | if (!ppd->lid) | 809 | if (!ppd->lid) |
@@ -806,6 +821,20 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp, | |||
806 | pkey, becn, 0, l4, priv->s_sc); | 821 | pkey, becn, 0, l4, priv->s_sc); |
807 | } | 822 | } |
808 | 823 | ||
824 | /** | ||
825 | * hfi1_make_ruc_header_9B - build a 9B header | ||
826 | * @qp: the queue pair | ||
827 | * @ohdr: a pointer to the destination header memory | ||
828 | * @bth0: bth0 passed in from the RC/UC builder | ||
829 | * @bth2: bth2 passed in from the RC/UC builder | ||
830 | * @middle: non zero implies indicates ahg "could" be used | ||
831 | * @ps: the current packet state | ||
832 | * | ||
833 | * This routine may disarm ahg under these situations: | ||
834 | * - packet needs a GRH | ||
835 | * - BECN needed | ||
836 | * - migration state not IB_MIG_MIGRATED | ||
837 | */ | ||
809 | static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | 838 | static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, |
810 | struct ib_other_headers *ohdr, | 839 | struct ib_other_headers *ohdr, |
811 | u32 bth0, u32 bth2, int middle, | 840 | u32 bth0, u32 bth2, int middle, |
@@ -839,6 +868,12 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | |||
839 | else | 868 | else |
840 | middle = 0; | 869 | middle = 0; |
841 | 870 | ||
871 | if (qp->s_flags & RVT_S_ECN) { | ||
872 | qp->s_flags &= ~RVT_S_ECN; | ||
873 | /* we recently received a FECN, so return a BECN */ | ||
874 | bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | ||
875 | middle = 0; | ||
876 | } | ||
842 | if (middle) | 877 | if (middle) |
843 | build_ahg(qp, bth2); | 878 | build_ahg(qp, bth2); |
844 | else | 879 | else |
@@ -846,11 +881,6 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp, | |||
846 | 881 | ||
847 | bth0 |= pkey; | 882 | bth0 |= pkey; |
848 | bth0 |= extra_bytes << 20; | 883 | bth0 |= extra_bytes << 20; |
849 | if (qp->s_flags & RVT_S_ECN) { | ||
850 | qp->s_flags &= ~RVT_S_ECN; | ||
851 | /* we recently received a FECN, so return a BECN */ | ||
852 | bth1 |= (IB_BECN_MASK << IB_BECN_SHIFT); | ||
853 | } | ||
854 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); | 884 | hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2); |
855 | hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh, | 885 | hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh, |
856 | lrh0, | 886 | lrh0, |