IB/mlx5: Support set qp counter
Support bind a qp with counter. If counter is null then bind the qp to the default counter. Different QP state has different operation: - RESET: Set the counter field so that it will take effective during RST2INIT change; - RTS: Issue an RTS2RTS change to update the QP counter; - Other: Set the counter field and mark the counter_pending flag, when QP is moved to RTS state and this flag is set, then issue an RTS2RTS modification to update the counter. Signed-off-by: Mark Zhang <markz@mellanox.com> Reviewed-by: Majd Dibbiny <majd@mellanox.com> Acked-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
Родитель
99fa331dc8
Коммит
d14133dd41
|
@ -439,6 +439,10 @@ struct mlx5_ib_qp {
|
||||||
u32 flags_en;
|
u32 flags_en;
|
||||||
/* storage for qp sub type when core qp type is IB_QPT_DRIVER */
|
/* storage for qp sub type when core qp type is IB_QPT_DRIVER */
|
||||||
enum ib_qp_type qp_sub_type;
|
enum ib_qp_type qp_sub_type;
|
||||||
|
/* A flag to indicate if there's a new counter is configured
|
||||||
|
* but not take effective
|
||||||
|
*/
|
||||||
|
u32 counter_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_ib_cq_buf {
|
struct mlx5_ib_cq_buf {
|
||||||
|
@ -1468,4 +1472,6 @@ void mlx5_ib_put_xlt_emergency_page(void);
|
||||||
int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
|
int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
|
||||||
struct mlx5_bfreg_info *bfregi, u32 bfregn,
|
struct mlx5_bfreg_info *bfregi, u32 bfregn,
|
||||||
bool dyn_bfreg);
|
bool dyn_bfreg);
|
||||||
|
|
||||||
|
int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
|
||||||
#endif /* MLX5_IB_H */
|
#endif /* MLX5_IB_H */
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <rdma/ib_umem.h>
|
#include <rdma/ib_umem.h>
|
||||||
#include <rdma/ib_cache.h>
|
#include <rdma/ib_cache.h>
|
||||||
#include <rdma/ib_user_verbs.h>
|
#include <rdma/ib_user_verbs.h>
|
||||||
|
#include <rdma/rdma_counter.h>
|
||||||
#include <linux/mlx5/fs.h>
|
#include <linux/mlx5/fs.h>
|
||||||
#include "mlx5_ib.h"
|
#include "mlx5_ib.h"
|
||||||
#include "ib_rep.h"
|
#include "ib_rep.h"
|
||||||
|
@ -3380,6 +3381,35 @@ static unsigned int get_tx_affinity(struct mlx5_ib_dev *dev,
|
||||||
return tx_port_affinity;
|
return tx_port_affinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __mlx5_ib_qp_set_counter(struct ib_qp *qp,
|
||||||
|
struct rdma_counter *counter)
|
||||||
|
{
|
||||||
|
struct mlx5_ib_dev *dev = to_mdev(qp->device);
|
||||||
|
struct mlx5_ib_qp *mqp = to_mqp(qp);
|
||||||
|
struct mlx5_qp_context context = {};
|
||||||
|
struct mlx5_ib_port *mibport = NULL;
|
||||||
|
struct mlx5_ib_qp_base *base;
|
||||||
|
u32 set_id;
|
||||||
|
|
||||||
|
if (!MLX5_CAP_GEN(dev->mdev, rts2rts_qp_counters_set_id))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (counter) {
|
||||||
|
set_id = counter->id;
|
||||||
|
} else {
|
||||||
|
mibport = &dev->port[mqp->port - 1];
|
||||||
|
set_id = mibport->cnts.set_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
base = &mqp->trans_qp.base;
|
||||||
|
context.qp_counter_set_usr_page &= cpu_to_be32(0xffffff);
|
||||||
|
context.qp_counter_set_usr_page |= cpu_to_be32(set_id << 24);
|
||||||
|
return mlx5_core_qp_modify(dev->mdev,
|
||||||
|
MLX5_CMD_OP_RTS2RTS_QP,
|
||||||
|
MLX5_QP_OPTPAR_COUNTER_SET_ID,
|
||||||
|
&context, &base->mqp);
|
||||||
|
}
|
||||||
|
|
||||||
static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||||
const struct ib_qp_attr *attr, int attr_mask,
|
const struct ib_qp_attr *attr, int attr_mask,
|
||||||
enum ib_qp_state cur_state,
|
enum ib_qp_state cur_state,
|
||||||
|
@ -3433,6 +3463,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||||
struct mlx5_ib_port *mibport = NULL;
|
struct mlx5_ib_port *mibport = NULL;
|
||||||
enum mlx5_qp_state mlx5_cur, mlx5_new;
|
enum mlx5_qp_state mlx5_cur, mlx5_new;
|
||||||
enum mlx5_qp_optpar optpar;
|
enum mlx5_qp_optpar optpar;
|
||||||
|
u32 set_id = 0;
|
||||||
int mlx5_st;
|
int mlx5_st;
|
||||||
int err;
|
int err;
|
||||||
u16 op;
|
u16 op;
|
||||||
|
@ -3595,8 +3626,12 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||||
port_num = 0;
|
port_num = 0;
|
||||||
|
|
||||||
mibport = &dev->port[port_num];
|
mibport = &dev->port[port_num];
|
||||||
|
if (ibqp->counter)
|
||||||
|
set_id = ibqp->counter->id;
|
||||||
|
else
|
||||||
|
set_id = mibport->cnts.set_id;
|
||||||
context->qp_counter_set_usr_page |=
|
context->qp_counter_set_usr_page |=
|
||||||
cpu_to_be32((u32)(mibport->cnts.set_id) << 24);
|
cpu_to_be32(set_id << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
|
if (!ibqp->uobject && cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT)
|
||||||
|
@ -3624,7 +3659,7 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||||
|
|
||||||
raw_qp_param.operation = op;
|
raw_qp_param.operation = op;
|
||||||
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
|
||||||
raw_qp_param.rq_q_ctr_id = mibport->cnts.set_id;
|
raw_qp_param.rq_q_ctr_id = set_id;
|
||||||
raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
|
raw_qp_param.set_mask |= MLX5_RAW_QP_MOD_SET_RQ_Q_CTR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3701,6 +3736,12 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
|
||||||
qp->db.db[MLX5_SND_DBR] = 0;
|
qp->db.db[MLX5_SND_DBR] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((new_state == IB_QPS_RTS) && qp->counter_pending) {
|
||||||
|
err = __mlx5_ib_qp_set_counter(ibqp, ibqp->counter);
|
||||||
|
if (!err)
|
||||||
|
qp->counter_pending = 0;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
kfree(context);
|
kfree(context);
|
||||||
return err;
|
return err;
|
||||||
|
@ -6435,3 +6476,34 @@ void mlx5_ib_drain_rq(struct ib_qp *qp)
|
||||||
|
|
||||||
handle_drain_completion(cq, &rdrain, dev);
|
handle_drain_completion(cq, &rdrain, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind a qp to a counter. If @counter is NULL then bind the qp to
|
||||||
|
* the default counter
|
||||||
|
*/
|
||||||
|
int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter)
|
||||||
|
{
|
||||||
|
struct mlx5_ib_qp *mqp = to_mqp(qp);
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
mutex_lock(&mqp->mutex);
|
||||||
|
if (mqp->state == IB_QPS_RESET) {
|
||||||
|
qp->counter = counter;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mqp->state == IB_QPS_RTS) {
|
||||||
|
err = __mlx5_ib_qp_set_counter(qp, counter);
|
||||||
|
if (!err)
|
||||||
|
qp->counter = counter;
|
||||||
|
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
mqp->counter_pending = 1;
|
||||||
|
qp->counter = counter;
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&mqp->mutex);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ enum mlx5_qp_optpar {
|
||||||
MLX5_QP_OPTPAR_CQN_RCV = 1 << 19,
|
MLX5_QP_OPTPAR_CQN_RCV = 1 << 19,
|
||||||
MLX5_QP_OPTPAR_DC_HS = 1 << 20,
|
MLX5_QP_OPTPAR_DC_HS = 1 << 20,
|
||||||
MLX5_QP_OPTPAR_DC_KEY = 1 << 21,
|
MLX5_QP_OPTPAR_DC_KEY = 1 << 21,
|
||||||
|
MLX5_QP_OPTPAR_COUNTER_SET_ID = 1 << 25,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mlx5_qp_state {
|
enum mlx5_qp_state {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче