aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSagi Grimberg <sagig@mellanox.com>2014-02-23 07:19:08 -0500
committerRoland Dreier <roland@purestorage.com>2014-03-07 14:26:49 -0500
commit6e5eadace1da7c57c1f10d55a484bda13c86dfed (patch)
treecc3bafc4cb62429c6ad466899ea42501d36b6b19 /drivers
parente1e66cc26457c2e9412f67618646ec2a441fc409 (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.c97
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
2050static 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
2079static 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
2050int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, 2103int 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 }