diff options
| -rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 97 |
1 files changed, 61 insertions, 36 deletions
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 01999f3744fb..a029009323ec 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
| @@ -2047,6 +2047,59 @@ static u8 get_fence(u8 fence, struct ib_send_wr *wr) | |||
| 2047 | } | 2047 | } |
| 2048 | } | 2048 | } |
| 2049 | 2049 | ||
| 2050 | static int begin_wqe(struct mlx5_ib_qp *qp, void **seg, | ||
| 2051 | struct mlx5_wqe_ctrl_seg **ctrl, | ||
| 2052 | struct ib_send_wr *wr, int *idx, | ||
| 2053 | int *size, int nreq) | ||
| 2054 | { | ||
| 2055 | int err = 0; | ||
| 2056 | |||
| 2057 | if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) { | ||
| 2058 | err = -ENOMEM; | ||
| 2059 | return err; | ||
| 2060 | } | ||
| 2061 | |||
| 2062 | *idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1); | ||
| 2063 | *seg = mlx5_get_send_wqe(qp, *idx); | ||
| 2064 | *ctrl = *seg; | ||
| 2065 | *(uint32_t *)(*seg + 8) = 0; | ||
| 2066 | (*ctrl)->imm = send_ieth(wr); | ||
| 2067 | (*ctrl)->fm_ce_se = qp->sq_signal_bits | | ||
| 2068 | (wr->send_flags & IB_SEND_SIGNALED ? | ||
| 2069 | MLX5_WQE_CTRL_CQ_UPDATE : 0) | | ||
| 2070 | (wr->send_flags & IB_SEND_SOLICITED ? | ||
| 2071 | MLX5_WQE_CTRL_SOLICITED : 0); | ||
| 2072 | |||
| 2073 | *seg += sizeof(**ctrl); | ||
| 2074 | *size = sizeof(**ctrl) / 16; | ||
| 2075 | |||
| 2076 | return err; | ||
| 2077 | } | ||
| 2078 | |||
| 2079 | static void finish_wqe(struct mlx5_ib_qp *qp, | ||
| 2080 | struct mlx5_wqe_ctrl_seg *ctrl, | ||
| 2081 | u8 size, unsigned idx, u64 wr_id, | ||
| 2082 | int nreq, u8 fence, u8 next_fence, | ||
| 2083 | u32 mlx5_opcode) | ||
| 2084 | { | ||
| 2085 | u8 opmod = 0; | ||
| 2086 | |||
| 2087 | ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8) | | ||
| 2088 | mlx5_opcode | ((u32)opmod << 24)); | ||
| 2089 | ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8)); | ||
| 2090 | ctrl->fm_ce_se |= fence; | ||
| 2091 | qp->fm_cache = next_fence; | ||
| 2092 | if (unlikely(qp->wq_sig)) | ||
| 2093 | ctrl->signature = wq_sig(ctrl); | ||
| 2094 | |||
| 2095 | qp->sq.wrid[idx] = wr_id; | ||
| 2096 | qp->sq.w_list[idx].opcode = mlx5_opcode; | ||
| 2097 | qp->sq.wqe_head[idx] = qp->sq.head + nreq; | ||
| 2098 | qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB); | ||
| 2099 | qp->sq.w_list[idx].next = qp->sq.cur_post; | ||
| 2100 | } | ||
| 2101 | |||
| 2102 | |||
| 2050 | int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 2103 | int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
| 2051 | struct ib_send_wr **bad_wr) | 2104 | struct ib_send_wr **bad_wr) |
| 2052 | { | 2105 | { |
| @@ -2060,7 +2113,6 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 2060 | int uninitialized_var(size); | 2113 | int uninitialized_var(size); |
| 2061 | void *qend = qp->sq.qend; | 2114 | void *qend = qp->sq.qend; |
| 2062 | unsigned long flags; | 2115 | unsigned long flags; |
| 2063 | u32 mlx5_opcode; | ||
| 2064 | unsigned idx; | 2116 | unsigned idx; |
| 2065 | int err = 0; | 2117 | int err = 0; |
| 2066 | int inl = 0; | 2118 | int inl = 0; |
| @@ -2069,7 +2121,6 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 2069 | int nreq; | 2121 | int nreq; |
| 2070 | int i; | 2122 | int i; |
| 2071 | u8 next_fence = 0; | 2123 | u8 next_fence = 0; |
| 2072 | u8 opmod = 0; | ||
| 2073 | u8 fence; | 2124 | u8 fence; |
| 2074 | 2125 | ||
| 2075 | spin_lock_irqsave(&qp->sq.lock, flags); | 2126 | spin_lock_irqsave(&qp->sq.lock, flags); |
| @@ -2082,36 +2133,23 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 2082 | goto out; | 2133 | goto out; |
| 2083 | } | 2134 | } |
| 2084 | 2135 | ||
| 2085 | if (unlikely(mlx5_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq))) { | 2136 | fence = qp->fm_cache; |
| 2137 | num_sge = wr->num_sge; | ||
| 2138 | if (unlikely(num_sge > qp->sq.max_gs)) { | ||
| 2086 | mlx5_ib_warn(dev, "\n"); | 2139 | mlx5_ib_warn(dev, "\n"); |
| 2087 | err = -ENOMEM; | 2140 | err = -ENOMEM; |
| 2088 | *bad_wr = wr; | 2141 | *bad_wr = wr; |
| 2089 | goto out; | 2142 | goto out; |
| 2090 | } | 2143 | } |
| 2091 | 2144 | ||
| 2092 | fence = qp->fm_cache; | 2145 | err = begin_wqe(qp, &seg, &ctrl, wr, &idx, &size, nreq); |
| 2093 | num_sge = wr->num_sge; | 2146 | if (err) { |
| 2094 | if (unlikely(num_sge > qp->sq.max_gs)) { | ||
| 2095 | mlx5_ib_warn(dev, "\n"); | 2147 | mlx5_ib_warn(dev, "\n"); |
| 2096 | err = -ENOMEM; | 2148 | err = -ENOMEM; |
| 2097 | *bad_wr = wr; | 2149 | *bad_wr = wr; |
| 2098 | goto out; | 2150 | goto out; |
| 2099 | } | 2151 | } |
| 2100 | 2152 | ||
| 2101 | idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1); | ||
| 2102 | seg = mlx5_get_send_wqe(qp, idx); | ||
| 2103 | ctrl = seg; | ||
| 2104 | *(uint32_t *)(seg + 8) = 0; | ||
| 2105 | ctrl->imm = send_ieth(wr); | ||
| 2106 | ctrl->fm_ce_se = qp->sq_signal_bits | | ||
| 2107 | (wr->send_flags & IB_SEND_SIGNALED ? | ||
| 2108 | MLX5_WQE_CTRL_CQ_UPDATE : 0) | | ||
| 2109 | (wr->send_flags & IB_SEND_SOLICITED ? | ||
| 2110 | MLX5_WQE_CTRL_SOLICITED : 0); | ||
| 2111 | |||
| 2112 | seg += sizeof(*ctrl); | ||
| 2113 | size = sizeof(*ctrl) / 16; | ||
| 2114 | |||
| 2115 | switch (ibqp->qp_type) { | 2153 | switch (ibqp->qp_type) { |
| 2116 | case IB_QPT_XRC_INI: | 2154 | case IB_QPT_XRC_INI: |
| 2117 | xrc = seg; | 2155 | xrc = seg; |
| @@ -2244,22 +2282,9 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
| 2244 | } | 2282 | } |
| 2245 | } | 2283 | } |
| 2246 | 2284 | ||
| 2247 | mlx5_opcode = mlx5_ib_opcode[wr->opcode]; | 2285 | finish_wqe(qp, ctrl, size, idx, wr->wr_id, nreq, |
| 2248 | ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8) | | 2286 | get_fence(fence, wr), next_fence, |
| 2249 | mlx5_opcode | | 2287 | mlx5_ib_opcode[wr->opcode]); |
| 2250 | ((u32)opmod << 24)); | ||
| 2251 | ctrl->qpn_ds = cpu_to_be32(size | (qp->mqp.qpn << 8)); | ||
| 2252 | ctrl->fm_ce_se |= get_fence(fence, wr); | ||
| 2253 | qp->fm_cache = next_fence; | ||
| 2254 | if (unlikely(qp->wq_sig)) | ||
| 2255 | ctrl->signature = wq_sig(ctrl); | ||
| 2256 | |||
| 2257 | qp->sq.wrid[idx] = wr->wr_id; | ||
| 2258 | qp->sq.w_list[idx].opcode = mlx5_opcode; | ||
| 2259 | qp->sq.wqe_head[idx] = qp->sq.head + nreq; | ||
| 2260 | qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB); | ||
| 2261 | qp->sq.w_list[idx].next = qp->sq.cur_post; | ||
| 2262 | |||
| 2263 | if (0) | 2288 | if (0) |
| 2264 | dump_wqe(qp, idx, size); | 2289 | dump_wqe(qp, idx, size); |
| 2265 | } | 2290 | } |
