net/mlx5: add flow query abstraction interface

Flow engine now supports multiple driver paths with each having
its own flow query implantation routine.
This patch adds an abstraction to the flow query routine in accordance
to commit 0c76d1c9a1 ("net/mlx5: add abstraction for multiple flow
drivers") done by Yongseok Koh.

Signed-off-by: Moti Haimovsky <motih@mellanox.com>
This commit is contained in:
Moti Haimovsky 2018-10-18 21:29:22 +03:00 committed by Ferruh Yigit
parent 743fdbeb45
commit 684dafe795
5 changed files with 162 additions and 67 deletions

View File

@ -1653,6 +1653,17 @@ flow_null_destroy(struct rte_eth_dev *dev __rte_unused,
{
}
static int
flow_null_query(struct rte_eth_dev *dev __rte_unused,
struct rte_flow *flow __rte_unused,
const struct rte_flow_action *actions __rte_unused,
void *data __rte_unused,
struct rte_flow_error *error __rte_unused)
{
rte_errno = ENOTSUP;
return -rte_errno;
}
/* Void driver to protect from null pointer reference. */
const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = {
.validate = flow_null_validate,
@ -1661,6 +1672,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = {
.apply = flow_null_apply,
.remove = flow_null_remove,
.destroy = flow_null_destroy,
.query = flow_null_query,
};
/**
@ -2344,92 +2356,45 @@ mlx5_flow_isolate(struct rte_eth_dev *dev,
}
/**
* Query flow counter.
* Query a flow.
*
* @param flow
* Pointer to the flow.
*
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
* @see rte_flow_query()
* @see rte_flow_ops
*/
static int
mlx5_flow_query_count(struct rte_flow *flow __rte_unused,
void *data __rte_unused,
struct rte_flow_error *error)
flow_drv_query(struct rte_eth_dev *dev,
struct rte_flow *flow,
const struct rte_flow_action *actions,
void *data,
struct rte_flow_error *error)
{
#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
if (flow->actions & MLX5_FLOW_ACTION_COUNT) {
struct rte_flow_query_count *qc = data;
uint64_t counters[2] = {0, 0};
struct ibv_query_counter_set_attr query_cs_attr = {
.cs = flow->counter->cs,
.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
};
struct ibv_counter_set_data query_out = {
.out = counters,
.outlen = 2 * sizeof(uint64_t),
};
int err = mlx5_glue->query_counter_set(&query_cs_attr,
&query_out);
const struct mlx5_flow_driver_ops *fops;
enum mlx5_flow_drv_type ftype = flow->drv_type;
if (err)
return rte_flow_error_set
(error, err,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"cannot read counter");
qc->hits_set = 1;
qc->bytes_set = 1;
qc->hits = counters[0] - flow->counter->hits;
qc->bytes = counters[1] - flow->counter->bytes;
if (qc->reset) {
flow->counter->hits = counters[0];
flow->counter->bytes = counters[1];
}
return 0;
}
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"flow does not have counter");
#endif
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"counters are not available");
assert(ftype > MLX5_FLOW_TYPE_MIN && ftype < MLX5_FLOW_TYPE_MAX);
fops = flow_get_drv_ops(ftype);
return fops->query(dev, flow, actions, data, error);
}
/**
* Query a flows.
* Query a flow.
*
* @see rte_flow_query()
* @see rte_flow_ops
*/
int
mlx5_flow_query(struct rte_eth_dev *dev __rte_unused,
mlx5_flow_query(struct rte_eth_dev *dev,
struct rte_flow *flow,
const struct rte_flow_action *actions,
void *data,
struct rte_flow_error *error)
{
int ret = 0;
int ret;
for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
switch (actions->type) {
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_COUNT:
ret = mlx5_flow_query_count(flow, data, error);
break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION,
actions,
"action not supported");
}
if (ret < 0)
return ret;
}
ret = flow_drv_query(dev, flow, actions, data, error);
if (ret < 0)
return ret;
return 0;
}

View File

@ -268,6 +268,11 @@ typedef void (*mlx5_flow_remove_t)(struct rte_eth_dev *dev,
struct rte_flow *flow);
typedef void (*mlx5_flow_destroy_t)(struct rte_eth_dev *dev,
struct rte_flow *flow);
typedef int (*mlx5_flow_query_t)(struct rte_eth_dev *dev,
struct rte_flow *flow,
const struct rte_flow_action *actions,
void *data,
struct rte_flow_error *error);
struct mlx5_flow_driver_ops {
mlx5_flow_validate_t validate;
mlx5_flow_prepare_t prepare;
@ -275,6 +280,7 @@ struct mlx5_flow_driver_ops {
mlx5_flow_apply_t apply;
mlx5_flow_remove_t remove;
mlx5_flow_destroy_t destroy;
mlx5_flow_query_t query;
};
/* mlx5_flow.c */

View File

@ -1363,6 +1363,24 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
}
}
/**
* Query a flow.
*
* @see rte_flow_query()
* @see rte_flow_ops
*/
static int
flow_dv_query(struct rte_eth_dev *dev __rte_unused,
struct rte_flow *flow __rte_unused,
const struct rte_flow_action *actions __rte_unused,
void *data __rte_unused,
struct rte_flow_error *error __rte_unused)
{
rte_errno = ENOTSUP;
return -rte_errno;
}
const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
.validate = flow_dv_validate,
.prepare = flow_dv_prepare,
@ -1370,6 +1388,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
.apply = flow_dv_apply,
.remove = flow_dv_remove,
.destroy = flow_dv_destroy,
.query = flow_dv_query,
};
#endif /* HAVE_IBV_FLOW_DV_SUPPORT */

View File

@ -2238,6 +2238,23 @@ flow_tcf_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
rte_free(dev_flow);
}
/**
* Query a flow.
*
* @see rte_flow_query()
* @see rte_flow_ops
*/
static int
flow_tcf_query(struct rte_eth_dev *dev __rte_unused,
struct rte_flow *flow __rte_unused,
const struct rte_flow_action *actions __rte_unused,
void *data __rte_unused,
struct rte_flow_error *error __rte_unused)
{
rte_errno = ENOTSUP;
return -rte_errno;
}
const struct mlx5_flow_driver_ops mlx5_flow_tcf_drv_ops = {
.validate = flow_tcf_validate,
.prepare = flow_tcf_prepare,
@ -2245,6 +2262,7 @@ const struct mlx5_flow_driver_ops mlx5_flow_tcf_drv_ops = {
.apply = flow_tcf_apply,
.remove = flow_tcf_remove,
.destroy = flow_tcf_destroy,
.query = flow_tcf_query,
};
/**

View File

@ -1651,6 +1651,92 @@ flow_verbs_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
return -rte_errno;
}
/**
* Query a flows.
*
* @see rte_flow_query()
* @see rte_flow_ops
*/
static int
flow_verbs_query_count(struct rte_eth_dev *dev __rte_unused,
struct rte_flow *flow __rte_unused,
void *data __rte_unused,
struct rte_flow_error *error)
{
#ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
if (flow->actions & MLX5_FLOW_ACTION_COUNT) {
struct rte_flow_query_count *qc = data;
uint64_t counters[2] = {0, 0};
struct ibv_query_counter_set_attr query_cs_attr = {
.cs = flow->counter->cs,
.query_flags = IBV_COUNTER_SET_FORCE_UPDATE,
};
struct ibv_counter_set_data query_out = {
.out = counters,
.outlen = 2 * sizeof(uint64_t),
};
int err = mlx5_glue->query_counter_set(&query_cs_attr,
&query_out);
if (err)
return rte_flow_error_set
(error, err,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"cannot read counter");
qc->hits_set = 1;
qc->bytes_set = 1;
qc->hits = counters[0] - flow->counter->hits;
qc->bytes = counters[1] - flow->counter->bytes;
if (qc->reset) {
flow->counter->hits = counters[0];
flow->counter->bytes = counters[1];
}
return 0;
}
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"flow does not have counter");
#endif
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"counters are not available");
}
/**
* Query a flow.
*
* @see rte_flow_query()
* @see rte_flow_ops
*/
static int
flow_verbs_query(struct rte_eth_dev *dev,
struct rte_flow *flow,
const struct rte_flow_action *actions,
void *data,
struct rte_flow_error *error)
{
int ret = -EINVAL;
for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
switch (actions->type) {
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_COUNT:
ret = flow_verbs_query_count(dev, flow, data, error);
break;
default:
return rte_flow_error_set(error, ENOTSUP,
RTE_FLOW_ERROR_TYPE_ACTION,
actions,
"action not supported");
}
}
return ret;
}
const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {
.validate = flow_verbs_validate,
.prepare = flow_verbs_prepare,
@ -1658,4 +1744,5 @@ const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {
.apply = flow_verbs_apply,
.remove = flow_verbs_remove,
.destroy = flow_verbs_destroy,
.query = flow_verbs_query,
};