diff options
author | Sagi Grimberg <sagig@mellanox.com> | 2014-02-23 07:19:08 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-03-07 14:26:49 -0500 |
commit | 6e5eadace1da7c57c1f10d55a484bda13c86dfed (patch) | |
tree | cc3bafc4cb62429c6ad466899ea42501d36b6b19 /drivers | |
parent | e1e66cc26457c2e9412f67618646ec2a441fc409 (diff) |
IB/mlx5: Break up wqe handling into begin & finish routines
As a preliminary step for signature feature which will require posting
multiple (3) WQEs for a single WR, we break post_send routine WQE
indexing into begin and finish routines.
This patch does not change any functionality.
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-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 | } |